@nanobpm/nano-workforce 0.97.0 → 0.97.1
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.
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [0.97.1](https://github.com/nanobpm/nano-workforce/compare/v0.97.0...v0.97.1) (2026-08-19)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **merge-loop:** give merge-blocked escalation a question + gw-escalated guard ([#329](https://github.com/nanobpm/nano-workforce/issues/329)) ([#331](https://github.com/nanobpm/nano-workforce/issues/331)) ([abb2952](https://github.com/nanobpm/nano-workforce/commit/abb2952b5ff5874ff928085167f4a0fd5f0580e5))
|
|
7
|
+
|
|
1
8
|
# [0.97.0](https://github.com/nanobpm/nano-workforce/compare/v0.96.1...v0.97.0) (2026-08-19)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// Regression guard for the question-less merge escalation defect (issue #329).
|
|
2
|
+
//
|
|
3
|
+
// The merge loop (`resources/processes/merge-loop.bpmn`) raised escalations with NO question
|
|
4
|
+
// whenever a PR was blocked by anything other than a merge conflict: `merge-esc-attempt` called
|
|
5
|
+
// `pr.persist-escalation` with no `question`/`status` ioMapping, and its output flowed
|
|
6
|
+
// UNCONDITIONALLY into `wait-merge-answer`. Two coupled defects fell out of that:
|
|
7
|
+
//
|
|
8
|
+
// 1. A blank question surfaced on the merge-driving inbox — the human was asked to answer but
|
|
9
|
+
// told nothing (observed live on nano-ide PR #354).
|
|
10
|
+
// 2. Per ADR 0002 §1 a blank question is a NON-escalation: `pr.persist-escalation` opens no row
|
|
11
|
+
// and returns `escalated:false`. The convergence loop honours this via a `gw-escalated`
|
|
12
|
+
// branch; the merge loop had none, so a question-less job still parked a dead
|
|
13
|
+
// `wait-merge-answer` with nothing for a human to answer.
|
|
14
|
+
//
|
|
15
|
+
// The fix (mirroring the convergence loop): give `merge-esc-attempt` a human-actionable
|
|
16
|
+
// `status`/`question` that distinguishes its four trigger conditions, and add a `gw-merge-escalated`
|
|
17
|
+
// guard so a `persist-escalation` returning `escalated:false` re-enters the loop (re-arms the
|
|
18
|
+
// poller) instead of parking a dead wait.
|
|
19
|
+
//
|
|
20
|
+
// These are pure text assertions over the committed BPMN (no engine), matching the repo's
|
|
21
|
+
// lightweight model-guard style (see mergeRebaseArm.test.ts, mergeEscalationUserTask.test.ts).
|
|
22
|
+
|
|
23
|
+
import { test } from "node:test";
|
|
24
|
+
import { assert, assertStringIncludes } from "#test-assert";
|
|
25
|
+
import { readFileSync } from "node:fs";
|
|
26
|
+
|
|
27
|
+
const bpmn = readFileSync("resources/processes/merge-loop.bpmn", "utf8");
|
|
28
|
+
// Collapse whitespace so attribute-order / line-wrapping churn doesn't make the assertions brittle.
|
|
29
|
+
const flat = bpmn.replace(/\s+/g, " ");
|
|
30
|
+
|
|
31
|
+
function flowHasId(id: string, source: string, target: string): boolean {
|
|
32
|
+
const m = flat.match(new RegExp(`<bpmn:sequenceFlow\\b[^>]*\\bid="${id}"[^>]*(?:/>|>)`));
|
|
33
|
+
if (!m) return false;
|
|
34
|
+
const tag = m[0];
|
|
35
|
+
return tag.includes(`sourceRef="${source}"`) && tag.includes(`targetRef="${target}"`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function gatewayDefault(id: string, def: string): boolean {
|
|
39
|
+
const m = flat.match(new RegExp(`<bpmn:exclusiveGateway\\b[^>]*\\bid="${id}"[^>]*>`));
|
|
40
|
+
if (!m) return false;
|
|
41
|
+
return m[0].includes(`default="${def}"`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// The <serviceTask> element for merge-esc-attempt, including its ioMapping. Unescape XML entities so
|
|
45
|
+
// FEEL string literals (authored as `"ready"` inside the attribute) read naturally here.
|
|
46
|
+
const escAttemptRaw = flat.match(/<bpmn:serviceTask\b[^>]*\bid="merge-esc-attempt"[\s\S]*?<\/bpmn:serviceTask>/);
|
|
47
|
+
const escAttempt = escAttemptRaw
|
|
48
|
+
? [escAttemptRaw[0].replace(/"/g, '"').replace(/&/g, "&").replace(/ /g, "\n")]
|
|
49
|
+
: null;
|
|
50
|
+
|
|
51
|
+
test("merge-esc-attempt carries a non-blank, human-actionable status + question", () => {
|
|
52
|
+
assert(escAttempt, "merge-esc-attempt service task must exist");
|
|
53
|
+
const el = escAttempt![0];
|
|
54
|
+
// Mirror the merge-esc-conflict mapping style: an explicit `blocked` status…
|
|
55
|
+
assertStringIncludes(el, "<zeebe:ioMapping", "merge-esc-attempt must set an ioMapping (was absent — the #329 defect)");
|
|
56
|
+
assertStringIncludes(el, 'target="status"', "merge-esc-attempt must set a `status`");
|
|
57
|
+
assertStringIncludes(el, 'target="question"', "merge-esc-attempt must set a non-blank `question`");
|
|
58
|
+
// Tighten: assert the explicit `status` INPUT MAPPING sets blocked, not merely the substring
|
|
59
|
+
// `="blocked"` (which the FEEL question's `agentVerdict = "blocked"` comparison would also satisfy
|
|
60
|
+
// even if the status mapping were removed/changed). Match tolerant of attribute order/spacing: the
|
|
61
|
+
// file is XML and a formatter could reorder `source`/`target` within the tag.
|
|
62
|
+
const escInputs = el.match(/<zeebe:input\b[^>]*\/>/g) ?? [];
|
|
63
|
+
const setsBlockedStatus = escInputs.some(
|
|
64
|
+
(t) => t.includes('target="status"') && t.includes('source="="blocked""'),
|
|
65
|
+
);
|
|
66
|
+
assert(setsBlockedStatus, "the explicit `status` input mapping must set `blocked`");
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test("arm-merge clears the prior verdict `status` so a stale `blocked` cannot misclassify the CI-fix SLA escalation", () => {
|
|
70
|
+
// merge-esc-attempt captures `agentVerdict = status` to split its CI could-not-fix vs SLA question
|
|
71
|
+
// arms. On the SLA boundary path (`f_ci_sla`) no worker sets a fresh `status`, and every escalation
|
|
72
|
+
// task overwrites `status = "blocked"` (merge-esc-attempt line 194, merge-esc-conflict line 174).
|
|
73
|
+
// Without a reset, a retry after any prior escalation re-enters fix-ci with `status` still
|
|
74
|
+
// "blocked", so an SLA timeout would render the wrong ("could not fix") question. arm-merge is the
|
|
75
|
+
// single loop hub every fix-ci entry passes through, so clearing `status` there (to null) each
|
|
76
|
+
// iteration guarantees a genuine SLA reads no stale verdict. Nothing between arm-merge and the next
|
|
77
|
+
// verdict-setter (fix-ci/rebase) reads `status`, so the reset is safe.
|
|
78
|
+
const armRaw = flat.match(/<bpmn:serviceTask\b[^>]*\bid="arm-merge"[\s\S]*?<\/bpmn:serviceTask>/);
|
|
79
|
+
assert(armRaw, "arm-merge service task must exist");
|
|
80
|
+
const armOutputs = armRaw![0].match(/<zeebe:output\b[^>]*\/>/g) ?? [];
|
|
81
|
+
const clearsStatus = armOutputs.some(
|
|
82
|
+
(t) => t.includes('target="status"') && t.includes('source="=null"'),
|
|
83
|
+
);
|
|
84
|
+
assert(clearsStatus, "arm-merge must reset `status` to null each loop iteration so a stale `blocked` cannot misclassify the SLA escalation");
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("the question distinguishes all four blocked/SLA triggers rather than a single generic string", () => {
|
|
88
|
+
// Four flows route into merge-esc-attempt — the gate `blocked` default, CI could-not-fix,
|
|
89
|
+
// rebase could-not-resolve, and the CI-fix SLA. Each is a legitimately different escalation and
|
|
90
|
+
// the question must explain which one fired.
|
|
91
|
+
assert(escAttempt, "merge-esc-attempt service task must exist");
|
|
92
|
+
const el = escAttempt![0];
|
|
93
|
+
// gate blocked (gw-merge default): distinguishes on the `ready` mergeState + surfaces mergeStatus.
|
|
94
|
+
assertStringIncludes(el, 'mergeState = "ready"', "must branch on the gate-blocked (ready) trigger");
|
|
95
|
+
assertStringIncludes(el, "mergeStatus", "the gate-blocked question must surface the merge result");
|
|
96
|
+
// rebase could-not-resolve (conflict arm).
|
|
97
|
+
assertStringIncludes(el, 'mergeState = "conflict"', "must branch on the rebase (conflict) trigger");
|
|
98
|
+
// CI could-not-fix vs CI SLA both arrive with mergeState = blocked — split on the agent verdict,
|
|
99
|
+
// captured into a dedicated `agentVerdict` binding so the escalation-classification `status =
|
|
100
|
+
// "blocked"` override in the SAME ioMapping cannot make the SLA branch unreachable (issue #329
|
|
101
|
+
// review). Assert the question branches on that binding, not on the overwritten `status`.
|
|
102
|
+
assertStringIncludes(el, "agentVerdict", "must capture the agent verdict into a dedicated binding");
|
|
103
|
+
assertStringIncludes(el, 'agentVerdict = "blocked"', "must branch CI could-not-fix vs SLA on the agent verdict binding, not the overwritten status");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test("a gw-merge-escalated guard honours persist-escalation's escalated:false (mirrors the convergence loop)", () => {
|
|
107
|
+
// The escalation output no longer flows UNCONDITIONALLY into the durable answer wait: it passes
|
|
108
|
+
// through a gateway that reads the worker's `escalated` output.
|
|
109
|
+
assert(
|
|
110
|
+
flowHasId("f_m_escA", "merge-esc-attempt", "gw-merge-escalated"),
|
|
111
|
+
"merge-esc-attempt must route through gw-merge-escalated, not straight to wait-merge-answer",
|
|
112
|
+
);
|
|
113
|
+
// escalated:true → park the native user task for a human to answer.
|
|
114
|
+
assert(
|
|
115
|
+
flowHasId("f_m_escWait", "gw-merge-escalated", "wait-merge-answer"),
|
|
116
|
+
"gw-merge-escalated → wait-merge-answer (escalated) missing",
|
|
117
|
+
);
|
|
118
|
+
const escWait = flat.match(/<bpmn:sequenceFlow[^>]*id="f_m_escWait"[\s\S]*?<\/bpmn:sequenceFlow>/);
|
|
119
|
+
assert(escWait, "f_m_escWait flow missing");
|
|
120
|
+
assertStringIncludes(escWait![0], "escalated = true", "the wait arm must be guarded by escalated = true");
|
|
121
|
+
// escalated:false (a non-escalation, e.g. a blank question) → re-enter the loop, NOT a dead wait.
|
|
122
|
+
assert(
|
|
123
|
+
gatewayDefault("gw-merge-escalated", "f_m_escReenter"),
|
|
124
|
+
"gw-merge-escalated must default to f_m_escReenter (re-enter, not park)",
|
|
125
|
+
);
|
|
126
|
+
assert(
|
|
127
|
+
flowHasId("f_m_escReenter", "gw-merge-escalated", "arm-merge"),
|
|
128
|
+
"f_m_escReenter must re-arm the merge poller instead of parking a dead wait-merge-answer",
|
|
129
|
+
);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test("regression: a question-less escalation can no longer park a dead wait-merge-answer", () => {
|
|
133
|
+
// The exact #329 wedge: `merge-esc-attempt → wait-merge-answer` as a direct, unconditional edge.
|
|
134
|
+
// It must be gone — the only path into the answer wait from the attempt arm is now guarded by
|
|
135
|
+
// `escalated = true`.
|
|
136
|
+
assert(
|
|
137
|
+
!flowHasId("f_m_escA", "merge-esc-attempt", "wait-merge-answer"),
|
|
138
|
+
"merge-esc-attempt must NOT flow directly into wait-merge-answer (the #329 dead-wait defect)",
|
|
139
|
+
);
|
|
140
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nanobpm/nano-workforce",
|
|
3
|
-
"version": "0.97.
|
|
3
|
+
"version": "0.97.1",
|
|
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",
|
|
@@ -96,12 +96,16 @@
|
|
|
96
96
|
<zeebe:properties>
|
|
97
97
|
<zeebe:property name="io.nanobpm.dataEnvelope.in" value="MergeArmIn" />
|
|
98
98
|
</zeebe:properties>
|
|
99
|
+
<zeebe:ioMapping>
|
|
100
|
+
<zeebe:output source="=null" target="status" />
|
|
101
|
+
</zeebe:ioMapping>
|
|
99
102
|
</bpmn:extensionElements>
|
|
100
103
|
<bpmn:incoming>f_m_deps</bpmn:incoming>
|
|
101
104
|
<bpmn:incoming>f_m_answer</bpmn:incoming>
|
|
102
105
|
<bpmn:incoming>f_ci_fixed</bpmn:incoming>
|
|
103
106
|
<bpmn:incoming>f_reb_rebased</bpmn:incoming>
|
|
104
107
|
<bpmn:incoming>f_m_evicted</bpmn:incoming>
|
|
108
|
+
<bpmn:incoming>f_m_escReenter</bpmn:incoming>
|
|
105
109
|
<bpmn:outgoing>f_m_arm</bpmn:outgoing>
|
|
106
110
|
</bpmn:serviceTask>
|
|
107
111
|
<bpmn:intermediateCatchEvent id="wait-mergeable" name="Wait: mergeable">
|
|
@@ -187,6 +191,11 @@
|
|
|
187
191
|
<zeebe:property name="io.nanobpm.dataEnvelope.in" value="EscalationIn" />
|
|
188
192
|
<zeebe:property name="io.nanobpm.dataEnvelope.out" value="EscalationOut" />
|
|
189
193
|
</zeebe:properties>
|
|
194
|
+
<zeebe:ioMapping>
|
|
195
|
+
<zeebe:input source="=status" target="agentVerdict" />
|
|
196
|
+
<zeebe:input source="="This PR cannot be merged and needs a human decision. " + (if mergeState = "conflict" then "The automated rebase agent could not resolve the merge conflicts on this branch. Resolve them manually (or reply with guidance), then reply to retry." else if mergeState = "ready" then "The merge attempt did not land (merge result: " + mergeStatus + "). Investigate why GitHub refused the merge, then reply to retry." else if agentVerdict = "blocked" then "The automated CI-fix agent could not make the required checks green. Fix the failing checks on the branch (or reply with guidance), then reply to retry." else "The automated CI-fix agent exceeded its time budget (SLA) before the required checks went green. Check its progress or intervene, then reply to retry.")" target="question" />
|
|
197
|
+
<zeebe:input source="="blocked"" target="status" />
|
|
198
|
+
</zeebe:ioMapping>
|
|
190
199
|
</bpmn:extensionElements>
|
|
191
200
|
<bpmn:incoming>f_m_gBlocked</bpmn:incoming>
|
|
192
201
|
<bpmn:incoming>f_ci_blocked</bpmn:incoming>
|
|
@@ -194,6 +203,11 @@
|
|
|
194
203
|
<bpmn:incoming>f_ci_sla</bpmn:incoming>
|
|
195
204
|
<bpmn:outgoing>f_m_escA</bpmn:outgoing>
|
|
196
205
|
</bpmn:serviceTask>
|
|
206
|
+
<bpmn:exclusiveGateway id="gw-merge-escalated" name="escalation opened?" default="f_m_escReenter">
|
|
207
|
+
<bpmn:incoming>f_m_escA</bpmn:incoming>
|
|
208
|
+
<bpmn:outgoing>f_m_escWait</bpmn:outgoing>
|
|
209
|
+
<bpmn:outgoing>f_m_escReenter</bpmn:outgoing>
|
|
210
|
+
</bpmn:exclusiveGateway>
|
|
197
211
|
<bpmn:userTask id="wait-merge-answer" name="Answer escalation">
|
|
198
212
|
<bpmn:extensionElements>
|
|
199
213
|
<zeebe:formDefinition formId="pr-escalation" />
|
|
@@ -204,7 +218,7 @@
|
|
|
204
218
|
</zeebe:ioMapping>
|
|
205
219
|
</bpmn:extensionElements>
|
|
206
220
|
<bpmn:incoming>f_m_escC</bpmn:incoming>
|
|
207
|
-
<bpmn:incoming>
|
|
221
|
+
<bpmn:incoming>f_m_escWait</bpmn:incoming>
|
|
208
222
|
<bpmn:outgoing>f_m_answerRecord</bpmn:outgoing>
|
|
209
223
|
</bpmn:userTask>
|
|
210
224
|
<bpmn:serviceTask id="record-merge-answer" name="Record answer">
|
|
@@ -363,7 +377,11 @@
|
|
|
363
377
|
<bpmn:sequenceFlow id="f_m_landed" sourceRef="wait-landed" targetRef="mark-merged" />
|
|
364
378
|
<bpmn:sequenceFlow id="f_m_done" sourceRef="mark-merged" targetRef="MergeEnd" />
|
|
365
379
|
<bpmn:sequenceFlow id="f_m_escC" sourceRef="merge-esc-conflict" targetRef="wait-merge-answer" />
|
|
366
|
-
<bpmn:sequenceFlow id="f_m_escA" sourceRef="merge-esc-attempt" targetRef="
|
|
380
|
+
<bpmn:sequenceFlow id="f_m_escA" sourceRef="merge-esc-attempt" targetRef="gw-merge-escalated" />
|
|
381
|
+
<bpmn:sequenceFlow id="f_m_escWait" sourceRef="gw-merge-escalated" targetRef="wait-merge-answer">
|
|
382
|
+
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=escalated = true</bpmn:conditionExpression>
|
|
383
|
+
</bpmn:sequenceFlow>
|
|
384
|
+
<bpmn:sequenceFlow id="f_m_escReenter" name="no escalation opened" sourceRef="gw-merge-escalated" targetRef="arm-merge" />
|
|
367
385
|
<bpmn:sequenceFlow id="f_m_answerRecord" sourceRef="wait-merge-answer" targetRef="record-merge-answer" />
|
|
368
386
|
<bpmn:sequenceFlow id="f_m_answer" sourceRef="record-merge-answer" targetRef="arm-merge" />
|
|
369
387
|
<bpmn:sequenceFlow id="f_reb_sla" name="agent SLA elapsed" sourceRef="be_rebase_sla" targetRef="merge-esc-conflict" />
|
|
@@ -440,11 +458,17 @@
|
|
|
440
458
|
<bpmndi:BPMNShape id="BPMNShape_merge-esc-attempt" bpmnElement="merge-esc-attempt">
|
|
441
459
|
<dc:Bounds x="1438" y="1040" width="100" height="80" />
|
|
442
460
|
</bpmndi:BPMNShape>
|
|
461
|
+
<bpmndi:BPMNShape id="BPMNShape_gw-merge-escalated" bpmnElement="gw-merge-escalated" isMarkerVisible="true">
|
|
462
|
+
<dc:Bounds x="1663" y="1055" width="50" height="50" />
|
|
463
|
+
<bpmndi:BPMNLabel>
|
|
464
|
+
<dc:Bounds x="1651" y="1022" width="74" height="28" />
|
|
465
|
+
</bpmndi:BPMNLabel>
|
|
466
|
+
</bpmndi:BPMNShape>
|
|
443
467
|
<bpmndi:BPMNShape id="BPMNShape_wait-merge-answer" bpmnElement="wait-merge-answer">
|
|
444
|
-
<dc:Bounds x="
|
|
468
|
+
<dc:Bounds x="1838" y="1040" width="100" height="80" />
|
|
445
469
|
</bpmndi:BPMNShape>
|
|
446
470
|
<bpmndi:BPMNShape id="BPMNShape_record-merge-answer" bpmnElement="record-merge-answer">
|
|
447
|
-
<dc:Bounds x="
|
|
471
|
+
<dc:Bounds x="2038" y="1040" width="100" height="80" />
|
|
448
472
|
</bpmndi:BPMNShape>
|
|
449
473
|
<bpmndi:BPMNShape id="BPMNShape_gw-ci-fix" bpmnElement="gw-ci-fix" isMarkerVisible="true">
|
|
450
474
|
<dc:Bounds x="863" y="1535" width="50" height="50" />
|
|
@@ -577,16 +601,25 @@
|
|
|
577
601
|
</bpmndi:BPMNEdge>
|
|
578
602
|
<bpmndi:BPMNEdge id="BPMNEdge_f_m_escC" bpmnElement="f_m_escC">
|
|
579
603
|
<di:waypoint x="1338" y="1560" />
|
|
580
|
-
<di:waypoint x="
|
|
581
|
-
<di:waypoint x="
|
|
604
|
+
<di:waypoint x="1888" y="1560" />
|
|
605
|
+
<di:waypoint x="1888" y="1120" />
|
|
606
|
+
</bpmndi:BPMNEdge>
|
|
607
|
+
<bpmndi:BPMNEdge id="BPMNEdge_f_m_escReenter" bpmnElement="f_m_escReenter">
|
|
608
|
+
<di:waypoint x="1688" y="1105" />
|
|
609
|
+
<di:waypoint x="1688" y="1140" />
|
|
610
|
+
<di:waypoint x="402" y="1140" />
|
|
611
|
+
<di:waypoint x="402" y="160" />
|
|
612
|
+
<bpmndi:BPMNLabel>
|
|
613
|
+
<dc:Bounds x="1008" y="1093" width="74" height="42" />
|
|
614
|
+
</bpmndi:BPMNLabel>
|
|
582
615
|
</bpmndi:BPMNEdge>
|
|
583
616
|
<bpmndi:BPMNEdge id="BPMNEdge_f_m_answerRecord" bpmnElement="f_m_answerRecord">
|
|
584
|
-
<di:waypoint x="
|
|
585
|
-
<di:waypoint x="
|
|
617
|
+
<di:waypoint x="1938" y="1080" />
|
|
618
|
+
<di:waypoint x="2038" y="1080" />
|
|
586
619
|
</bpmndi:BPMNEdge>
|
|
587
620
|
<bpmndi:BPMNEdge id="BPMNEdge_f_m_answer" bpmnElement="f_m_answer">
|
|
588
|
-
<di:waypoint x="
|
|
589
|
-
<di:waypoint x="
|
|
621
|
+
<di:waypoint x="2088" y="1120" />
|
|
622
|
+
<di:waypoint x="2088" y="1140" />
|
|
590
623
|
<di:waypoint x="402" y="1140" />
|
|
591
624
|
<di:waypoint x="402" y="160" />
|
|
592
625
|
</bpmndi:BPMNEdge>
|
|
@@ -626,13 +659,13 @@
|
|
|
626
659
|
<bpmndi:BPMNEdge id="BPMNEdge_f_ci_go" bpmnElement="f_ci_go">
|
|
627
660
|
<di:waypoint x="888" y="1585" />
|
|
628
661
|
<di:waypoint x="888" y="1605" />
|
|
629
|
-
<di:waypoint x="
|
|
630
|
-
<di:waypoint x="
|
|
662
|
+
<di:waypoint x="2158" y="1605" />
|
|
663
|
+
<di:waypoint x="2158" y="555" />
|
|
631
664
|
<di:waypoint x="1018" y="555" />
|
|
632
665
|
<di:waypoint x="1018" y="580" />
|
|
633
666
|
<di:waypoint x="1038" y="580" />
|
|
634
667
|
<bpmndi:BPMNLabel>
|
|
635
|
-
<dc:Bounds x="
|
|
668
|
+
<dc:Bounds x="2163" y="1066" width="49" height="28" />
|
|
636
669
|
</bpmndi:BPMNLabel>
|
|
637
670
|
</bpmndi:BPMNEdge>
|
|
638
671
|
<bpmndi:BPMNEdge id="BPMNEdge_f_ci_blocked" bpmnElement="f_ci_blocked">
|
|
@@ -657,14 +690,14 @@
|
|
|
657
690
|
<di:waypoint x="933" y="280" />
|
|
658
691
|
<di:waypoint x="933" y="305" />
|
|
659
692
|
<di:waypoint x="1558" y="305" />
|
|
660
|
-
<di:waypoint x="1558" y="
|
|
661
|
-
<di:waypoint x="1418" y="
|
|
693
|
+
<di:waypoint x="1558" y="1125" />
|
|
694
|
+
<di:waypoint x="1418" y="1125" />
|
|
662
695
|
<di:waypoint x="1418" y="875" />
|
|
663
696
|
<di:waypoint x="1018" y="875" />
|
|
664
697
|
<di:waypoint x="1018" y="900" />
|
|
665
698
|
<di:waypoint x="1038" y="900" />
|
|
666
699
|
<bpmndi:BPMNLabel>
|
|
667
|
-
<dc:Bounds x="
|
|
700
|
+
<dc:Bounds x="1563" y="701" width="49" height="28" />
|
|
668
701
|
</bpmndi:BPMNLabel>
|
|
669
702
|
</bpmndi:BPMNEdge>
|
|
670
703
|
<bpmndi:BPMNEdge id="BPMNEdge_f_reb_blocked" bpmnElement="f_reb_blocked">
|
|
@@ -718,7 +751,11 @@
|
|
|
718
751
|
</bpmndi:BPMNEdge>
|
|
719
752
|
<bpmndi:BPMNEdge id="BPMNEdge_f_m_escA" bpmnElement="f_m_escA">
|
|
720
753
|
<di:waypoint x="1538" y="1080" />
|
|
721
|
-
<di:waypoint x="
|
|
754
|
+
<di:waypoint x="1663" y="1080" />
|
|
755
|
+
</bpmndi:BPMNEdge>
|
|
756
|
+
<bpmndi:BPMNEdge id="BPMNEdge_f_m_escWait" bpmnElement="f_m_escWait">
|
|
757
|
+
<di:waypoint x="1713" y="1080" />
|
|
758
|
+
<di:waypoint x="1838" y="1080" />
|
|
722
759
|
</bpmndi:BPMNEdge>
|
|
723
760
|
<bpmndi:BPMNEdge id="BPMNEdge_f_reb_sla" bpmnElement="f_reb_sla">
|
|
724
761
|
<di:waypoint x="1088" y="978" />
|