@nanobpm/nano-workforce 0.70.0 → 0.70.2

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.
@@ -48,20 +48,39 @@ Because several agents may run on the same host at once:
48
48
 
49
49
  ## What to do in a round
50
50
 
51
- 1. **Read the latest review.** Fetch the newest Copilot review + its inline
52
- comments on the PR (`gh pr view`, `gh api .../pulls/{n}/reviews`, `.../comments`).
51
+ 1. **Read the latest review AND every still-open thread.** Fetch the newest Copilot
52
+ review + its inline comments on the PR (`gh pr view`, `gh api .../pulls/{n}/reviews`,
53
+ `.../comments`). Then **also enumerate every UNRESOLVED review thread on the PR**,
54
+ not just the latest review's comments — findings accumulate as durable threads, so
55
+ an earlier round's comment stays open until someone resolves it, and the newest
56
+ review will **not** re-list it. Treat the full set of open threads as your backlog
57
+ for this round, not only the latest review:
58
+
59
+ ```sh
60
+ # Every open thread across ALL reviews (this is your real backlog, oldest included):
61
+ # `pageInfo{hasNextPage endCursor}` surfaces truncation AND gives you the cursor to page with: if
62
+ # `hasNextPage` is `true` there are >100 threads this page can't see — re-run passing that
63
+ # `endCursor` back as `$after` until `hasNextPage` is `false`; never treat one page as "every"
64
+ # thread. Omit `-F after=…` (leaving `$after` null) for the first page.
65
+ gh api graphql -f query='query($o:String!,$r:String!,$n:Int!,$after:String){repository(owner:$o,name:$r){
66
+ pullRequest(number:$n){reviewThreads(first:100,after:$after){pageInfo{hasNextPage endCursor}nodes{id isResolved path line
67
+ comments(first:100){nodes{databaseId author{login} body}}}}}}}' -F o=OWNER -F r=REPO -F n=PR # add -F after=END_CURSOR to page
68
+ ```
69
+
53
70
  Also read Copilot's **suppressed / low-confidence** advisories — the collapsed
54
71
  "low confidence" list Copilot folds into the **review body** (`.../reviews`
55
72
  `body`). These are NOT in the default inline-comment API set, so a plain
56
73
  `.../comments` read misses them; scan the review body for them explicitly.
57
74
  If `answer` is present, treat it as the human's decision on the escalation you
58
75
  raised last round and act on it first.
59
- 2. **Triage each comment** into: *fix* (correct, worth doing), *nitpick* (apply
76
+ 2. **Triage each item** into: *fix* (correct, worth doing), *nitpick* (apply
60
77
  silently), *needs human input* (design/product/tradeoff you can't decide), or
61
- *push back* (wrong / false positive — reply with evidence, make no change).
62
- Triage the suppressed / low-confidence advisories the **same** way but do not
63
- treat "suppressed" as either automatically actionable or automatically ignorable:
64
- if one is a **cheap, correct** robustness/correctness win, just do it (a
78
+ *push back* (wrong / false positive — reply with evidence, make no change). Triage
79
+ **every open thread from step 1**, including ones raised in earlier rounds that the
80
+ latest review did not repeat do not skip a thread just because it is not in the
81
+ newest review. Triage the suppressed / low-confidence advisories the **same** way —
82
+ but do not treat "suppressed" as either automatically actionable or automatically
83
+ ignorable: if one is a **cheap, correct** robustness/correctness win, just do it (a
65
84
  *nitpick*); otherwise **decline it explicitly with a one-line rationale in your
66
85
  `summary`** (e.g. "declined suppressed advisory X — input already validated
67
86
  upstream at Y"). Never silently drop one.
@@ -93,6 +112,26 @@ Because several agents may run on the same host at once:
93
112
  # Resolve the thread whose databaseId matched the comment you handled:
94
113
  gh api graphql -f query='mutation($id:ID!){resolveReviewThread(input:{threadId:$id}){thread{isResolved}}}' -F id=THREAD_NODE_ID
95
114
  ```
115
+ 5a. **Acknowledge every suppressed / low-confidence advisory with a resolvable ack
116
+ thread.** Suppressed advisories live in the review **body**, not as inline
117
+ comment threads, so they cannot be resolved and Copilot **re-lists them every
118
+ round**. The process now *deterministically blocks convergence* until each one
119
+ carries a **resolved** acknowledgement, so a decision you only wrote into your
120
+ `summary` is invisible to the gate. For each suppressed advisory you applied or
121
+ declined (step 2), post a **new review comment thread** whose body contains the
122
+ verbatim marker **`nano-ack: <path>:<line>`** — copied exactly from Copilot's
123
+ bold `**<path>:<line>**` header for that advisory — then **resolve** that thread.
124
+ The gate matches on the marker **text**, so the thread may sit on any valid diff
125
+ line; only the exact `path:line` string must match. Example:
126
+
127
+ ```sh
128
+ # Post the ack thread (pick any changed line in the diff for path/line). Use the PR's real HEAD
129
+ # SHA as commit_id — `git rev-parse HEAD` can drift from the PR head; ask GitHub:
130
+ CID=$(gh api repos/OWNER/REPO/pulls/PR --jq .head.sha)
131
+ gh api repos/OWNER/REPO/pulls/PR/comments -f commit_id="$CID" -f path=PATH -F line=LINE -f side=RIGHT \
132
+ -f body='Applied. nano-ack: <path>:<line>' # or: 'Declined, false positive — <reason>. nano-ack: <path>:<line>'
133
+ # Then resolve it exactly like any other thread (map its databaseId -> thread node id -> resolveReviewThread).
134
+ ```
96
135
  6. **Do NOT request, re-request, or remove the reviewer yourself.** Keeping
97
136
  Copilot attached is the **process's** job: a deterministic poller ensures a
98
137
  Copilot review is requested (idempotently) whenever this PR is waiting, and it
@@ -118,11 +157,18 @@ Consider the PR **converged** when the latest review has no actionable comment:
118
157
  - every new comment is a nitpick you already handled or intentionally declined,
119
158
  **or**
120
159
  - the only remaining items are suppressed / low-confidence advisories you have
121
- triaged and either applied or declined-with-rationale (a suppressed advisory
122
- you have recorded a decision on does **not** block convergence), **or**
160
+ triaged and either applied or declined-with-rationale **and acknowledged with a
161
+ resolved `nano-ack:` thread** (step 5a) an advisory you have merely decided on
162
+ in prose still **blocks** convergence until its ack thread is resolved, **or**
123
163
  - Copilot is looping — reiterating a point you already addressed or pushed back
124
164
  on (two rounds of the same substantive point = converged).
125
165
 
166
+ Returning `converged` is necessary but **not sufficient**: after you return it the
167
+ process runs a deterministic gate that re-checks GitHub and will **block** convergence
168
+ (routing to a human) while **any** review thread is unresolved or **any** suppressed
169
+ advisory lacks a resolved `nano-ack:` thread. Resolve every thread and acknowledge
170
+ every advisory (steps 5 + 5a) *before* you converge, or the PR bounces to a human.
171
+
126
172
  ### No review has landed yet — return `waiting`, do NOT escalate
127
173
 
128
174
  A PR is **not** converged merely because there are zero reviews and zero
@@ -33,6 +33,24 @@
33
33
  <nano:extend name="prUrl" type="string" optional="true" />
34
34
  <nano:extend name="abandonUrl" type="string" optional="true" />
35
35
  </nano:shape>
36
+ <nano:shape id="PrProgressCheckIn" name="Check progress — input">
37
+ <nano:extend name="prKey" type="string" />
38
+ <nano:extend name="status" type="string" optional="true" />
39
+ <nano:extend name="repo" type="string" optional="true" />
40
+ <nano:extend name="prNumber" type="integer" optional="true" />
41
+ </nano:shape>
42
+ <nano:shape id="PrProgressCheckOut" name="Check progress — result">
43
+ <nano:extend name="progressed" type="boolean" />
44
+ </nano:shape>
45
+ <nano:shape id="PrConvergeGateIn" name="Converge gate — input">
46
+ <nano:extend name="prKey" type="string" />
47
+ <nano:extend name="repo" type="string" optional="true" />
48
+ <nano:extend name="prNumber" type="integer" optional="true" />
49
+ </nano:shape>
50
+ <nano:shape id="PrConvergeGateOut" name="Converge gate — result">
51
+ <nano:extend name="convergeBlocked" type="boolean" />
52
+ <nano:extend name="convergeBlockReason" type="string" optional="true" />
53
+ </nano:shape>
36
54
  <nano:shape id="EscalationIn" name="Record escalation — input">
37
55
  <nano:extend name="prKey" type="string" />
38
56
  <nano:extend name="round" type="integer" />
@@ -118,8 +136,40 @@
118
136
  <bpmn:incoming>f_guardOk</bpmn:incoming>
119
137
  <bpmn:outgoing>f_roundWait</bpmn:outgoing>
120
138
  </bpmn:serviceTask>
121
- <bpmn:eventBasedGateway id="gw-review-wait" name="review ready or timeout?">
139
+ <bpmn:serviceTask id="check-progress" name="Check progress">
140
+ <bpmn:extensionElements>
141
+ <zeebe:taskDefinition type="pr.progress-check" />
142
+ <zeebe:properties>
143
+ <zeebe:property name="io.nanobpm.dataEnvelope.in" value="PrProgressCheckIn" />
144
+ <zeebe:property name="io.nanobpm.dataEnvelope.out" value="PrProgressCheckOut" />
145
+ </zeebe:properties>
146
+ </bpmn:extensionElements>
122
147
  <bpmn:incoming>f_roundWait</bpmn:incoming>
148
+ <bpmn:outgoing>f_checkGate</bpmn:outgoing>
149
+ </bpmn:serviceTask>
150
+ <bpmn:exclusiveGateway id="gw-progress" name="progress made?" default="f_progressOk">
151
+ <bpmn:incoming>f_checkGate</bpmn:incoming>
152
+ <bpmn:outgoing>f_noProgress</bpmn:outgoing>
153
+ <bpmn:outgoing>f_progressOk</bpmn:outgoing>
154
+ </bpmn:exclusiveGateway>
155
+ <bpmn:serviceTask id="persist-escalation-noprogress" name="Escalate: no progress">
156
+ <bpmn:extensionElements>
157
+ <zeebe:taskDefinition type="pr.persist-escalation" />
158
+ <zeebe:properties>
159
+ <zeebe:property name="io.nanobpm.dataEnvelope.in" value="EscalationIn" />
160
+ <zeebe:property name="io.nanobpm.dataEnvelope.out" value="EscalationOut" />
161
+ </zeebe:properties>
162
+ <zeebe:ioMapping>
163
+ <zeebe:input source="=&#34;blocked&#34;" target="status" />
164
+ <zeebe:input source="=false" target="recordRound" />
165
+ <zeebe:input source="=&#34;Round &#34; + string(round) + &#34; reported the review comments were addressed, but the PR head did not advance (no commit was pushed), so another review round would loop on identical code. A human must decide how to proceed (reply to resume the loop).&#34;" target="question" />
166
+ </zeebe:ioMapping>
167
+ </bpmn:extensionElements>
168
+ <bpmn:incoming>f_noProgress</bpmn:incoming>
169
+ <bpmn:outgoing>f_noprogressWait</bpmn:outgoing>
170
+ </bpmn:serviceTask>
171
+ <bpmn:eventBasedGateway id="gw-review-wait" name="review ready or timeout?">
172
+ <bpmn:incoming>f_progressOk</bpmn:incoming>
123
173
  <bpmn:outgoing>f_toReviewWait</bpmn:outgoing>
124
174
  <bpmn:outgoing>f_toReviewTimeout</bpmn:outgoing>
125
175
  </bpmn:eventBasedGateway>
@@ -199,6 +249,8 @@
199
249
  <bpmn:incoming>f_escWait</bpmn:incoming>
200
250
  <bpmn:incoming>f_maxWait</bpmn:incoming>
201
251
  <bpmn:incoming>f_stalledWait</bpmn:incoming>
252
+ <bpmn:incoming>f_noprogressWait</bpmn:incoming>
253
+ <bpmn:incoming>f_blockedWait</bpmn:incoming>
202
254
  <bpmn:outgoing>f_answerRecord</bpmn:outgoing>
203
255
  </bpmn:userTask>
204
256
  <bpmn:serviceTask id="record-answer" name="Record answer">
@@ -222,17 +274,55 @@
222
274
  <zeebe:property name="io.nanobpm.dataEnvelope.in" value="PrFinalizeIn" />
223
275
  </zeebe:properties>
224
276
  </bpmn:extensionElements>
225
- <bpmn:incoming>f_converged</bpmn:incoming>
277
+ <bpmn:incoming>f_convergeOk</bpmn:incoming>
226
278
  <bpmn:outgoing>f_finalize</bpmn:outgoing>
227
279
  </bpmn:serviceTask>
280
+ <bpmn:serviceTask id="check-converge" name="Check review comments">
281
+ <bpmn:extensionElements>
282
+ <zeebe:taskDefinition type="pr.converge-gate" />
283
+ <zeebe:properties>
284
+ <zeebe:property name="io.nanobpm.dataEnvelope.in" value="PrConvergeGateIn" />
285
+ <zeebe:property name="io.nanobpm.dataEnvelope.out" value="PrConvergeGateOut" />
286
+ </zeebe:properties>
287
+ </bpmn:extensionElements>
288
+ <bpmn:incoming>f_converged</bpmn:incoming>
289
+ <bpmn:outgoing>f_toConvergeGate</bpmn:outgoing>
290
+ </bpmn:serviceTask>
291
+ <bpmn:exclusiveGateway id="gw-converge-gate" name="comments addressed?" default="f_convergeOk">
292
+ <bpmn:incoming>f_toConvergeGate</bpmn:incoming>
293
+ <bpmn:outgoing>f_convergeBlocked</bpmn:outgoing>
294
+ <bpmn:outgoing>f_convergeOk</bpmn:outgoing>
295
+ </bpmn:exclusiveGateway>
296
+ <bpmn:serviceTask id="persist-escalation-blockedcomments" name="Escalate: unaddressed comments">
297
+ <bpmn:extensionElements>
298
+ <zeebe:taskDefinition type="pr.persist-escalation" />
299
+ <zeebe:properties>
300
+ <zeebe:property name="io.nanobpm.dataEnvelope.in" value="EscalationIn" />
301
+ <zeebe:property name="io.nanobpm.dataEnvelope.out" value="EscalationOut" />
302
+ </zeebe:properties>
303
+ <zeebe:ioMapping>
304
+ <zeebe:input source="=&#34;blocked&#34;" target="status" />
305
+ <zeebe:input source="=false" target="recordRound" />
306
+ <zeebe:input source="=convergeBlockReason" target="question" />
307
+ </zeebe:ioMapping>
308
+ </bpmn:extensionElements>
309
+ <bpmn:incoming>f_convergeBlocked</bpmn:incoming>
310
+ <bpmn:outgoing>f_blockedWait</bpmn:outgoing>
311
+ </bpmn:serviceTask>
228
312
  <bpmn:endEvent id="End" name="Converged">
229
313
  <bpmn:incoming>f_finalize</bpmn:incoming>
230
314
  </bpmn:endEvent>
231
315
  <bpmn:sequenceFlow id="f_start" sourceRef="Start" targetRef="review-round" />
232
316
  <bpmn:sequenceFlow id="f_toStatus" sourceRef="review-round" targetRef="gw-status" />
233
- <bpmn:sequenceFlow id="f_converged" name="converged" sourceRef="gw-status" targetRef="persist-converged">
317
+ <bpmn:sequenceFlow id="f_converged" name="converged" sourceRef="gw-status" targetRef="check-converge">
234
318
  <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=status = "converged"</bpmn:conditionExpression>
235
319
  </bpmn:sequenceFlow>
320
+ <bpmn:sequenceFlow id="f_toConvergeGate" sourceRef="check-converge" targetRef="gw-converge-gate" />
321
+ <bpmn:sequenceFlow id="f_convergeBlocked" name="unaddressed comments" sourceRef="gw-converge-gate" targetRef="persist-escalation-blockedcomments">
322
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=convergeBlocked = true</bpmn:conditionExpression>
323
+ </bpmn:sequenceFlow>
324
+ <bpmn:sequenceFlow id="f_convergeOk" name="addressed / default" sourceRef="gw-converge-gate" targetRef="persist-converged" />
325
+ <bpmn:sequenceFlow id="f_blockedWait" sourceRef="persist-escalation-blockedcomments" targetRef="wait-answer" />
236
326
  <bpmn:sequenceFlow id="f_addressed" name="addressed / default" sourceRef="gw-status" targetRef="gw-guard" />
237
327
  <bpmn:sequenceFlow id="f_waiting" name="waiting" sourceRef="gw-status" targetRef="gw-guard">
238
328
  <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=status = "waiting"</bpmn:conditionExpression>
@@ -244,7 +334,13 @@
244
334
  <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=round &gt;= maxRounds</bpmn:conditionExpression>
245
335
  </bpmn:sequenceFlow>
246
336
  <bpmn:sequenceFlow id="f_guardOk" name="continue" sourceRef="gw-guard" targetRef="persist-round" />
247
- <bpmn:sequenceFlow id="f_roundWait" sourceRef="persist-round" targetRef="gw-review-wait" />
337
+ <bpmn:sequenceFlow id="f_roundWait" sourceRef="persist-round" targetRef="check-progress" />
338
+ <bpmn:sequenceFlow id="f_checkGate" sourceRef="check-progress" targetRef="gw-progress" />
339
+ <bpmn:sequenceFlow id="f_noProgress" name="no progress" sourceRef="gw-progress" targetRef="persist-escalation-noprogress">
340
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=progressed = false</bpmn:conditionExpression>
341
+ </bpmn:sequenceFlow>
342
+ <bpmn:sequenceFlow id="f_progressOk" name="progress / default" sourceRef="gw-progress" targetRef="gw-review-wait" />
343
+ <bpmn:sequenceFlow id="f_noprogressWait" sourceRef="persist-escalation-noprogress" targetRef="wait-answer" />
248
344
  <bpmn:sequenceFlow id="f_toReviewWait" sourceRef="gw-review-wait" targetRef="wait-review" />
249
345
  <bpmn:sequenceFlow id="f_toReviewTimeout" sourceRef="gw-review-wait" targetRef="wait-review-timeout" />
250
346
  <bpmn:sequenceFlow id="f_reviewLoop" sourceRef="wait-review" targetRef="review-round" />
@@ -278,34 +374,46 @@
278
374
  </bpmndi:BPMNLabel>
279
375
  </bpmndi:BPMNShape>
280
376
  <bpmndi:BPMNShape id="BPMNShape_gw-guard" bpmnElement="gw-guard" isMarkerVisible="true">
281
- <dc:Bounds x="916" y="255" width="50" height="50" />
377
+ <dc:Bounds x="941" y="415" width="50" height="50" />
282
378
  <bpmndi:BPMNLabel>
283
- <dc:Bounds x="899" y="310" width="85" height="14" />
379
+ <dc:Bounds x="924" y="470" width="85" height="14" />
284
380
  </bpmndi:BPMNLabel>
285
381
  </bpmndi:BPMNShape>
286
382
  <bpmndi:BPMNShape id="BPMNShape_persist-round" bpmnElement="persist-round">
287
- <dc:Bounds x="1066" y="240" width="100" height="80" />
383
+ <dc:Bounds x="1116" y="400" width="100" height="80" />
384
+ </bpmndi:BPMNShape>
385
+ <bpmndi:BPMNShape id="BPMNShape_check-progress" bpmnElement="check-progress">
386
+ <dc:Bounds x="1316" y="400" width="100" height="80" />
387
+ </bpmndi:BPMNShape>
388
+ <bpmndi:BPMNShape id="BPMNShape_gw-progress" bpmnElement="gw-progress" isMarkerVisible="true">
389
+ <dc:Bounds x="1516" y="415" width="50" height="50" />
390
+ <bpmndi:BPMNLabel>
391
+ <dc:Bounds x="1511" y="382" width="60" height="28" />
392
+ </bpmndi:BPMNLabel>
393
+ </bpmndi:BPMNShape>
394
+ <bpmndi:BPMNShape id="BPMNShape_persist-escalation-noprogress" bpmnElement="persist-escalation-noprogress">
395
+ <dc:Bounds x="1666" y="720" width="100" height="80" />
288
396
  </bpmndi:BPMNShape>
289
397
  <bpmndi:BPMNShape id="BPMNShape_gw-review-wait" bpmnElement="gw-review-wait" isMarkerVisible="true">
290
- <dc:Bounds x="1266" y="255" width="50" height="50" />
398
+ <dc:Bounds x="1691" y="415" width="50" height="50" />
291
399
  <bpmndi:BPMNLabel>
292
- <dc:Bounds x="1247" y="222" width="88" height="28" />
400
+ <dc:Bounds x="1672" y="382" width="88" height="28" />
293
401
  </bpmndi:BPMNLabel>
294
402
  </bpmndi:BPMNShape>
295
403
  <bpmndi:BPMNShape id="BPMNShape_wait-review" bpmnElement="wait-review">
296
- <dc:Bounds x="1416" y="262" width="36" height="36" />
404
+ <dc:Bounds x="1866" y="422" width="36" height="36" />
297
405
  <bpmndi:BPMNLabel>
298
- <dc:Bounds x="1390" y="229" width="88" height="28" />
406
+ <dc:Bounds x="1840" y="389" width="88" height="28" />
299
407
  </bpmndi:BPMNLabel>
300
408
  </bpmndi:BPMNShape>
301
409
  <bpmndi:BPMNShape id="BPMNShape_wait-review-timeout" bpmnElement="wait-review-timeout">
302
- <dc:Bounds x="1416" y="422" width="36" height="36" />
410
+ <dc:Bounds x="1866" y="582" width="36" height="36" />
303
411
  <bpmndi:BPMNLabel>
304
- <dc:Bounds x="1406" y="463" width="56" height="42" />
412
+ <dc:Bounds x="1856" y="623" width="56" height="42" />
305
413
  </bpmndi:BPMNLabel>
306
414
  </bpmndi:BPMNShape>
307
415
  <bpmndi:BPMNShape id="BPMNShape_persist-review-stalled" bpmnElement="persist-review-stalled">
308
- <dc:Bounds x="1552" y="400" width="100" height="80" />
416
+ <dc:Bounds x="2002" y="560" width="100" height="80" />
309
417
  </bpmndi:BPMNShape>
310
418
  <bpmndi:BPMNShape id="BPMNShape_persist-escalation" bpmnElement="persist-escalation">
311
419
  <dc:Bounds x="566" y="560" width="100" height="80" />
@@ -317,21 +425,33 @@
317
425
  </bpmndi:BPMNLabel>
318
426
  </bpmndi:BPMNShape>
319
427
  <bpmndi:BPMNShape id="BPMNShape_persist-escalation-maxrounds" bpmnElement="persist-escalation-maxrounds">
320
- <dc:Bounds x="1066" y="560" width="100" height="80" />
428
+ <dc:Bounds x="1116" y="880" width="100" height="80" />
321
429
  </bpmndi:BPMNShape>
322
430
  <bpmndi:BPMNShape id="BPMNShape_wait-answer" bpmnElement="wait-answer">
323
- <dc:Bounds x="1752" y="400" width="100" height="80" />
431
+ <dc:Bounds x="2202" y="240" width="100" height="80" />
324
432
  </bpmndi:BPMNShape>
325
433
  <bpmndi:BPMNShape id="BPMNShape_record-answer" bpmnElement="record-answer">
326
- <dc:Bounds x="1952" y="400" width="100" height="80" />
434
+ <dc:Bounds x="2402" y="240" width="100" height="80" />
327
435
  </bpmndi:BPMNShape>
328
436
  <bpmndi:BPMNShape id="BPMNShape_persist-converged" bpmnElement="persist-converged">
437
+ <dc:Bounds x="916" y="80" width="100" height="80" />
438
+ </bpmndi:BPMNShape>
439
+ <bpmndi:BPMNShape id="BPMNShape_check-converge" bpmnElement="check-converge">
329
440
  <dc:Bounds x="566" y="80" width="100" height="80" />
330
441
  </bpmndi:BPMNShape>
442
+ <bpmndi:BPMNShape id="BPMNShape_gw-converge-gate" bpmnElement="gw-converge-gate" isMarkerVisible="true">
443
+ <dc:Bounds x="766" y="95" width="50" height="50" />
444
+ <bpmndi:BPMNLabel>
445
+ <dc:Bounds x="754" y="62" width="74" height="28" />
446
+ </bpmndi:BPMNLabel>
447
+ </bpmndi:BPMNShape>
448
+ <bpmndi:BPMNShape id="BPMNShape_persist-escalation-blockedcomments" bpmnElement="persist-escalation-blockedcomments">
449
+ <dc:Bounds x="916" y="240" width="100" height="80" />
450
+ </bpmndi:BPMNShape>
331
451
  <bpmndi:BPMNShape id="BPMNShape_End" bpmnElement="End">
332
- <dc:Bounds x="773" y="102" width="36" height="36" />
452
+ <dc:Bounds x="1148" y="102" width="36" height="36" />
333
453
  <bpmndi:BPMNLabel>
334
- <dc:Bounds x="757" y="143" width="69" height="14" />
454
+ <dc:Bounds x="1132" y="143" width="69" height="14" />
335
455
  </bpmndi:BPMNLabel>
336
456
  </bpmndi:BPMNShape>
337
457
  <bpmndi:BPMNEdge id="BPMNEdge_f_start" bpmnElement="f_start">
@@ -349,53 +469,83 @@
349
469
  <dc:Bounds x="483" y="98" width="67" height="14" />
350
470
  </bpmndi:BPMNLabel>
351
471
  </bpmndi:BPMNEdge>
352
- <bpmndi:BPMNEdge id="BPMNEdge_f_finalize" bpmnElement="f_finalize">
472
+ <bpmndi:BPMNEdge id="BPMNEdge_f_toConvergeGate" bpmnElement="f_toConvergeGate">
353
473
  <di:waypoint x="666" y="120" />
354
- <di:waypoint x="773" y="120" />
474
+ <di:waypoint x="766" y="120" />
475
+ </bpmndi:BPMNEdge>
476
+ <bpmndi:BPMNEdge id="BPMNEdge_f_convergeOk" bpmnElement="f_convergeOk">
477
+ <di:waypoint x="816" y="120" />
478
+ <di:waypoint x="916" y="120" />
479
+ <bpmndi:BPMNLabel>
480
+ <dc:Bounds x="827" y="125" width="78" height="28" />
481
+ </bpmndi:BPMNLabel>
482
+ </bpmndi:BPMNEdge>
483
+ <bpmndi:BPMNEdge id="BPMNEdge_f_finalize" bpmnElement="f_finalize">
484
+ <di:waypoint x="1016" y="120" />
485
+ <di:waypoint x="1148" y="120" />
355
486
  </bpmndi:BPMNEdge>
356
487
  <bpmndi:BPMNEdge id="BPMNEdge_f_guardOk" bpmnElement="f_guardOk">
357
- <di:waypoint x="966" y="280" />
358
- <di:waypoint x="1066" y="280" />
488
+ <di:waypoint x="991" y="440" />
489
+ <di:waypoint x="1116" y="440" />
359
490
  <bpmndi:BPMNLabel>
360
- <dc:Bounds x="976" y="258" width="60" height="14" />
491
+ <dc:Bounds x="1014" y="418" width="60" height="14" />
361
492
  </bpmndi:BPMNLabel>
362
493
  </bpmndi:BPMNEdge>
363
494
  <bpmndi:BPMNEdge id="BPMNEdge_f_roundWait" bpmnElement="f_roundWait">
364
- <di:waypoint x="1166" y="280" />
365
- <di:waypoint x="1266" y="280" />
495
+ <di:waypoint x="1216" y="440" />
496
+ <di:waypoint x="1316" y="440" />
497
+ </bpmndi:BPMNEdge>
498
+ <bpmndi:BPMNEdge id="BPMNEdge_f_checkGate" bpmnElement="f_checkGate">
499
+ <di:waypoint x="1416" y="440" />
500
+ <di:waypoint x="1516" y="440" />
501
+ </bpmndi:BPMNEdge>
502
+ <bpmndi:BPMNEdge id="BPMNEdge_f_progressOk" bpmnElement="f_progressOk">
503
+ <di:waypoint x="1566" y="440" />
504
+ <di:waypoint x="1691" y="440" />
505
+ <bpmndi:BPMNLabel>
506
+ <dc:Bounds x="1591" y="407" width="71" height="28" />
507
+ </bpmndi:BPMNLabel>
366
508
  </bpmndi:BPMNEdge>
367
509
  <bpmndi:BPMNEdge id="BPMNEdge_f_toReviewWait" bpmnElement="f_toReviewWait">
368
- <di:waypoint x="1316" y="280" />
369
- <di:waypoint x="1416" y="280" />
510
+ <di:waypoint x="1741" y="440" />
511
+ <di:waypoint x="1866" y="440" />
370
512
  </bpmndi:BPMNEdge>
371
513
  <bpmndi:BPMNEdge id="BPMNEdge_f_reviewLoop" bpmnElement="f_reviewLoop">
372
- <di:waypoint x="1434" y="298" />
373
- <di:waypoint x="1434" y="340" />
374
- <di:waypoint x="266" y="340" />
514
+ <di:waypoint x="1884" y="458" />
515
+ <di:waypoint x="1884" y="500" />
516
+ <di:waypoint x="266" y="500" />
375
517
  <di:waypoint x="266" y="160" />
376
518
  </bpmndi:BPMNEdge>
377
519
  <bpmndi:BPMNEdge id="BPMNEdge_f_escReenter" bpmnElement="f_escReenter">
378
520
  <di:waypoint x="791" y="575" />
521
+ <di:waypoint x="791" y="440" />
522
+ <di:waypoint x="941" y="440" />
523
+ <bpmndi:BPMNLabel>
524
+ <dc:Bounds x="796" y="507" width="74" height="42" />
525
+ </bpmndi:BPMNLabel>
526
+ </bpmndi:BPMNEdge>
527
+ <bpmndi:BPMNEdge id="BPMNEdge_f_convergeBlocked" bpmnElement="f_convergeBlocked">
528
+ <di:waypoint x="791" y="145" />
379
529
  <di:waypoint x="791" y="280" />
380
530
  <di:waypoint x="916" y="280" />
381
531
  <bpmndi:BPMNLabel>
382
- <dc:Bounds x="796" y="407" width="74" height="42" />
532
+ <dc:Bounds x="796" y="199" width="81" height="28" />
383
533
  </bpmndi:BPMNLabel>
384
534
  </bpmndi:BPMNEdge>
385
535
  <bpmndi:BPMNEdge id="BPMNEdge_f_addressed" bpmnElement="f_addressed">
386
536
  <di:waypoint x="441" y="145" />
387
- <di:waypoint x="441" y="280" />
388
- <di:waypoint x="916" y="280" />
537
+ <di:waypoint x="441" y="440" />
538
+ <di:waypoint x="941" y="440" />
389
539
  <bpmndi:BPMNLabel>
390
- <dc:Bounds x="446" y="199" width="78" height="28" />
540
+ <dc:Bounds x="446" y="279" width="78" height="28" />
391
541
  </bpmndi:BPMNLabel>
392
542
  </bpmndi:BPMNEdge>
393
543
  <bpmndi:BPMNEdge id="BPMNEdge_f_waiting" bpmnElement="f_waiting">
394
544
  <di:waypoint x="441" y="145" />
395
- <di:waypoint x="441" y="280" />
396
- <di:waypoint x="916" y="280" />
545
+ <di:waypoint x="441" y="440" />
546
+ <di:waypoint x="941" y="440" />
397
547
  <bpmndi:BPMNLabel>
398
- <dc:Bounds x="380" y="206" width="56" height="14" />
548
+ <dc:Bounds x="380" y="286" width="56" height="14" />
399
549
  </bpmndi:BPMNLabel>
400
550
  </bpmndi:BPMNEdge>
401
551
  <bpmndi:BPMNEdge id="BPMNEdge_f_escalate" bpmnElement="f_escalate">
@@ -403,57 +553,78 @@
403
553
  <di:waypoint x="441" y="600" />
404
554
  <di:waypoint x="566" y="600" />
405
555
  <bpmndi:BPMNLabel>
406
- <dc:Bounds x="446" y="426" width="81" height="28" />
556
+ <dc:Bounds x="446" y="506" width="81" height="28" />
407
557
  </bpmndi:BPMNLabel>
408
558
  </bpmndi:BPMNEdge>
409
559
  <bpmndi:BPMNEdge id="BPMNEdge_f_guardMax" bpmnElement="f_guardMax">
410
- <di:waypoint x="966" y="280" />
411
- <di:waypoint x="1046" y="280" />
412
- <di:waypoint x="1046" y="600" />
413
- <di:waypoint x="1066" y="600" />
560
+ <di:waypoint x="991" y="440" />
561
+ <di:waypoint x="1096" y="440" />
562
+ <di:waypoint x="1096" y="920" />
563
+ <di:waypoint x="1116" y="920" />
564
+ <bpmndi:BPMNLabel>
565
+ <dc:Bounds x="1101" y="673" width="74" height="14" />
566
+ </bpmndi:BPMNLabel>
567
+ </bpmndi:BPMNEdge>
568
+ <bpmndi:BPMNEdge id="BPMNEdge_f_noProgress" bpmnElement="f_noProgress">
569
+ <di:waypoint x="1566" y="440" />
570
+ <di:waypoint x="1646" y="440" />
571
+ <di:waypoint x="1646" y="760" />
572
+ <di:waypoint x="1666" y="760" />
414
573
  <bpmndi:BPMNLabel>
415
- <dc:Bounds x="1051" y="433" width="74" height="14" />
574
+ <dc:Bounds x="1563" y="593" width="78" height="14" />
416
575
  </bpmndi:BPMNLabel>
417
576
  </bpmndi:BPMNEdge>
418
577
  <bpmndi:BPMNEdge id="BPMNEdge_f_toReviewTimeout" bpmnElement="f_toReviewTimeout">
419
- <di:waypoint x="1291" y="305" />
420
- <di:waypoint x="1291" y="440" />
421
- <di:waypoint x="1416" y="440" />
578
+ <di:waypoint x="1716" y="465" />
579
+ <di:waypoint x="1716" y="600" />
580
+ <di:waypoint x="1866" y="600" />
422
581
  </bpmndi:BPMNEdge>
423
582
  <bpmndi:BPMNEdge id="BPMNEdge_f_escWait" bpmnElement="f_escWait">
424
583
  <di:waypoint x="791" y="625" />
425
- <di:waypoint x="791" y="645" />
426
- <di:waypoint x="1732" y="645" />
427
- <di:waypoint x="1732" y="460" />
428
- <di:waypoint x="1752" y="460" />
584
+ <di:waypoint x="791" y="980" />
585
+ <di:waypoint x="2182" y="980" />
586
+ <di:waypoint x="2182" y="300" />
587
+ <di:waypoint x="2202" y="300" />
588
+ </bpmndi:BPMNEdge>
589
+ <bpmndi:BPMNEdge id="BPMNEdge_f_blockedWait" bpmnElement="f_blockedWait">
590
+ <di:waypoint x="1016" y="280" />
591
+ <di:waypoint x="2202" y="280" />
592
+ </bpmndi:BPMNEdge>
593
+ <bpmndi:BPMNEdge id="BPMNEdge_f_noprogressWait" bpmnElement="f_noprogressWait">
594
+ <di:waypoint x="1766" y="780" />
595
+ <di:waypoint x="1786" y="780" />
596
+ <di:waypoint x="1786" y="980" />
597
+ <di:waypoint x="2252" y="980" />
598
+ <di:waypoint x="2252" y="320" />
429
599
  </bpmndi:BPMNEdge>
430
600
  <bpmndi:BPMNEdge id="BPMNEdge_f_reviewStalled" bpmnElement="f_reviewStalled">
431
- <di:waypoint x="1452" y="440" />
432
- <di:waypoint x="1552" y="440" />
601
+ <di:waypoint x="1902" y="600" />
602
+ <di:waypoint x="2002" y="600" />
433
603
  </bpmndi:BPMNEdge>
434
604
  <bpmndi:BPMNEdge id="BPMNEdge_f_stalledWait" bpmnElement="f_stalledWait">
435
- <di:waypoint x="1652" y="440" />
436
- <di:waypoint x="1752" y="440" />
605
+ <di:waypoint x="2052" y="560" />
606
+ <di:waypoint x="2052" y="280" />
607
+ <di:waypoint x="2202" y="280" />
437
608
  </bpmndi:BPMNEdge>
438
609
  <bpmndi:BPMNEdge id="BPMNEdge_f_escGate" bpmnElement="f_escGate">
439
610
  <di:waypoint x="666" y="600" />
440
611
  <di:waypoint x="766" y="600" />
441
612
  </bpmndi:BPMNEdge>
442
613
  <bpmndi:BPMNEdge id="BPMNEdge_f_maxWait" bpmnElement="f_maxWait">
443
- <di:waypoint x="1166" y="620" />
444
- <di:waypoint x="1186" y="620" />
445
- <di:waypoint x="1186" y="645" />
446
- <di:waypoint x="1802" y="645" />
447
- <di:waypoint x="1802" y="480" />
614
+ <di:waypoint x="1216" y="940" />
615
+ <di:waypoint x="1236" y="940" />
616
+ <di:waypoint x="1236" y="980" />
617
+ <di:waypoint x="2252" y="980" />
618
+ <di:waypoint x="2252" y="320" />
448
619
  </bpmndi:BPMNEdge>
449
620
  <bpmndi:BPMNEdge id="BPMNEdge_f_answerRecord" bpmnElement="f_answerRecord">
450
- <di:waypoint x="1852" y="440" />
451
- <di:waypoint x="1952" y="440" />
621
+ <di:waypoint x="2302" y="280" />
622
+ <di:waypoint x="2402" y="280" />
452
623
  </bpmndi:BPMNEdge>
453
624
  <bpmndi:BPMNEdge id="BPMNEdge_f_answerLoop" bpmnElement="f_answerLoop">
454
- <di:waypoint x="2002" y="480" />
455
- <di:waypoint x="2002" y="660" />
456
- <di:waypoint x="266" y="660" />
625
+ <di:waypoint x="2452" y="320" />
626
+ <di:waypoint x="2452" y="340" />
627
+ <di:waypoint x="266" y="340" />
457
628
  <di:waypoint x="266" y="160" />
458
629
  </bpmndi:BPMNEdge>
459
630
  </bpmndi:BPMNPlane>