@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.
@@ -189,6 +189,7 @@
189
189
  <bpmn:incoming>f_m_mBlocked</bpmn:incoming>
190
190
  <bpmn:incoming>f_ci_giveup</bpmn:incoming>
191
191
  <bpmn:incoming>f_reb_giveup</bpmn:incoming>
192
+ <bpmn:incoming>f_reb_sla</bpmn:incoming>
192
193
  <bpmn:outgoing>f_m_escC</bpmn:outgoing>
193
194
  </bpmn:serviceTask>
194
195
  <bpmn:serviceTask id="merge-esc-attempt" name="Escalate: merge blocked">
@@ -202,6 +203,7 @@
202
203
  <bpmn:incoming>f_m_gBlocked</bpmn:incoming>
203
204
  <bpmn:incoming>f_ci_blocked</bpmn:incoming>
204
205
  <bpmn:incoming>f_reb_blocked</bpmn:incoming>
206
+ <bpmn:incoming>f_ci_sla</bpmn:incoming>
205
207
  <bpmn:outgoing>f_m_escA</bpmn:outgoing>
206
208
  </bpmn:serviceTask>
207
209
  <bpmn:intermediateCatchEvent id="wait-merge-answer" name="Wait: escalation answered">
@@ -233,6 +235,12 @@
233
235
  <bpmn:incoming>f_ci_go</bpmn:incoming>
234
236
  <bpmn:outgoing>f_ci_done</bpmn:outgoing>
235
237
  </bpmn:serviceTask>
238
+ <bpmn:boundaryEvent id="be_fixci_sla" name="SLA elapsed" attachedToRef="fix-ci">
239
+ <bpmn:outgoing>f_ci_sla</bpmn:outgoing>
240
+ <bpmn:timerEventDefinition id="ted_fixci_sla">
241
+ <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">=agentSlaTimeout</bpmn:timeDuration>
242
+ </bpmn:timerEventDefinition>
243
+ </bpmn:boundaryEvent>
236
244
  <bpmn:exclusiveGateway id="gw-ci-result" name="fixed?" default="f_ci_reconcile">
237
245
  <bpmn:incoming>f_ci_done</bpmn:incoming>
238
246
  <bpmn:outgoing>f_ci_fixed</bpmn:outgoing>
@@ -263,6 +271,12 @@
263
271
  <bpmn:incoming>f_reb_go</bpmn:incoming>
264
272
  <bpmn:outgoing>f_reb_done</bpmn:outgoing>
265
273
  </bpmn:serviceTask>
274
+ <bpmn:boundaryEvent id="be_rebase_sla" name="SLA elapsed" attachedToRef="rebase">
275
+ <bpmn:outgoing>f_reb_sla</bpmn:outgoing>
276
+ <bpmn:timerEventDefinition id="ted_rebase_sla">
277
+ <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">=agentSlaTimeout</bpmn:timeDuration>
278
+ </bpmn:timerEventDefinition>
279
+ </bpmn:boundaryEvent>
266
280
  <bpmn:exclusiveGateway id="gw-rebase-result" name="rebased?" default="f_reb_reconcile">
267
281
  <bpmn:incoming>f_reb_done</bpmn:incoming>
268
282
  <bpmn:outgoing>f_reb_rebased</bpmn:outgoing>
@@ -342,6 +356,8 @@
342
356
  <bpmn:sequenceFlow id="f_m_escC" sourceRef="merge-esc-conflict" targetRef="wait-merge-answer" />
343
357
  <bpmn:sequenceFlow id="f_m_escA" sourceRef="merge-esc-attempt" targetRef="wait-merge-answer" />
344
358
  <bpmn:sequenceFlow id="f_m_answer" sourceRef="wait-merge-answer" targetRef="arm-merge" />
359
+ <bpmn:sequenceFlow id="f_reb_sla" name="agent SLA elapsed" sourceRef="be_rebase_sla" targetRef="merge-esc-conflict" />
360
+ <bpmn:sequenceFlow id="f_ci_sla" name="agent SLA elapsed" sourceRef="be_fixci_sla" targetRef="merge-esc-attempt" />
345
361
  </bpmn:process>
346
362
  <bpmndi:BPMNDiagram id="BPMNDiagram_merge-loop">
347
363
  <bpmndi:BPMNPlane id="BPMNPlane_merge-loop" bpmnElement="merge-loop">
@@ -382,57 +398,57 @@
382
398
  </bpmndi:BPMNLabel>
383
399
  </bpmndi:BPMNShape>
384
400
  <bpmndi:BPMNShape id="BPMNShape_eg-landed" bpmnElement="eg-landed" isMarkerVisible="true">
385
- <dc:Bounds x="1238" y="255" width="50" height="50" />
401
+ <dc:Bounds x="1263" y="255" width="50" height="50" />
386
402
  <bpmndi:BPMNLabel>
387
- <dc:Bounds x="1231" y="222" width="64" height="28" />
403
+ <dc:Bounds x="1256" y="222" width="64" height="28" />
388
404
  </bpmndi:BPMNLabel>
389
405
  </bpmndi:BPMNShape>
390
406
  <bpmndi:BPMNShape id="BPMNShape_wait-landed" bpmnElement="wait-landed">
391
- <dc:Bounds x="1420" y="262" width="36" height="36" />
407
+ <dc:Bounds x="1470" y="262" width="36" height="36" />
392
408
  <bpmndi:BPMNLabel>
393
- <dc:Bounds x="1396" y="229" width="85" height="28" />
409
+ <dc:Bounds x="1446" y="229" width="85" height="28" />
394
410
  </bpmndi:BPMNLabel>
395
411
  </bpmndi:BPMNShape>
396
412
  <bpmndi:BPMNShape id="BPMNShape_wait-evicted" bpmnElement="wait-evicted">
397
- <dc:Bounds x="1420" y="422" width="36" height="36" />
413
+ <dc:Bounds x="1470" y="422" width="36" height="36" />
398
414
  <bpmndi:BPMNLabel>
399
- <dc:Bounds x="1394" y="375" width="88" height="42" />
415
+ <dc:Bounds x="1444" y="375" width="88" height="42" />
400
416
  </bpmndi:BPMNLabel>
401
417
  </bpmndi:BPMNShape>
402
418
  <bpmndi:BPMNShape id="BPMNShape_mark-merged" bpmnElement="mark-merged">
403
- <dc:Bounds x="1588" y="80" width="100" height="80" />
419
+ <dc:Bounds x="1638" y="80" width="100" height="80" />
404
420
  </bpmndi:BPMNShape>
405
421
  <bpmndi:BPMNShape id="BPMNShape_MergeEnd" bpmnElement="MergeEnd">
406
- <dc:Bounds x="1788" y="102" width="36" height="36" />
422
+ <dc:Bounds x="1838" y="102" width="36" height="36" />
407
423
  <bpmndi:BPMNLabel>
408
- <dc:Bounds x="1781" y="143" width="50" height="14" />
424
+ <dc:Bounds x="1831" y="143" width="50" height="14" />
409
425
  </bpmndi:BPMNLabel>
410
426
  </bpmndi:BPMNShape>
411
427
  <bpmndi:BPMNShape id="BPMNShape_merge-esc-conflict" bpmnElement="merge-esc-conflict">
412
- <dc:Bounds x="1038" y="720" width="100" height="80" />
428
+ <dc:Bounds x="1238" y="1520" width="100" height="80" />
413
429
  </bpmndi:BPMNShape>
414
430
  <bpmndi:BPMNShape id="BPMNShape_merge-esc-attempt" bpmnElement="merge-esc-attempt">
415
- <dc:Bounds x="1388" y="560" width="100" height="80" />
431
+ <dc:Bounds x="1438" y="1040" width="100" height="80" />
416
432
  </bpmndi:BPMNShape>
417
433
  <bpmndi:BPMNShape id="BPMNShape_wait-merge-answer" bpmnElement="wait-merge-answer">
418
- <dc:Bounds x="1620" y="582" width="36" height="36" />
434
+ <dc:Bounds x="1670" y="1062" width="36" height="36" />
419
435
  <bpmndi:BPMNLabel>
420
- <dc:Bounds x="1541" y="683" width="74" height="42" />
436
+ <dc:Bounds x="1731" y="1103" width="74" height="42" />
421
437
  </bpmndi:BPMNLabel>
422
438
  </bpmndi:BPMNShape>
423
439
  <bpmndi:BPMNShape id="BPMNShape_gw-ci-fix" bpmnElement="gw-ci-fix" isMarkerVisible="true">
424
- <dc:Bounds x="863" y="735" width="50" height="50" />
440
+ <dc:Bounds x="863" y="1535" width="50" height="50" />
425
441
  <bpmndi:BPMNLabel>
426
- <dc:Bounds x="844" y="716" width="89" height="14" />
442
+ <dc:Bounds x="769" y="1553" width="89" height="14" />
427
443
  </bpmndi:BPMNLabel>
428
444
  </bpmndi:BPMNShape>
429
445
  <bpmndi:BPMNShape id="BPMNShape_fix-ci" bpmnElement="fix-ci">
430
- <dc:Bounds x="1038" y="880" width="100" height="80" />
446
+ <dc:Bounds x="1038" y="560" width="100" height="80" />
431
447
  </bpmndi:BPMNShape>
432
448
  <bpmndi:BPMNShape id="BPMNShape_gw-ci-result" bpmnElement="gw-ci-result" isMarkerVisible="true">
433
- <dc:Bounds x="1238" y="895" width="50" height="50" />
449
+ <dc:Bounds x="1263" y="575" width="50" height="50" />
434
450
  <bpmndi:BPMNLabel>
435
- <dc:Bounds x="1240" y="876" width="46" height="14" />
451
+ <dc:Bounds x="1225" y="630" width="46" height="14" />
436
452
  </bpmndi:BPMNLabel>
437
453
  </bpmndi:BPMNShape>
438
454
  <bpmndi:BPMNShape id="BPMNShape_gw-rebase" bpmnElement="gw-rebase" isMarkerVisible="true">
@@ -442,16 +458,28 @@
442
458
  </bpmndi:BPMNLabel>
443
459
  </bpmndi:BPMNShape>
444
460
  <bpmndi:BPMNShape id="BPMNShape_rebase" bpmnElement="rebase">
445
- <dc:Bounds x="1038" y="1200" width="100" height="80" />
461
+ <dc:Bounds x="1038" y="880" width="100" height="80" />
446
462
  </bpmndi:BPMNShape>
447
463
  <bpmndi:BPMNShape id="BPMNShape_gw-rebase-result" bpmnElement="gw-rebase-result" isMarkerVisible="true">
448
- <dc:Bounds x="1238" y="1215" width="50" height="50" />
464
+ <dc:Bounds x="1263" y="895" width="50" height="50" />
449
465
  <bpmndi:BPMNLabel>
450
- <dc:Bounds x="1193" y="1270" width="60" height="14" />
466
+ <dc:Bounds x="1218" y="950" width="60" height="14" />
451
467
  </bpmndi:BPMNLabel>
452
468
  </bpmndi:BPMNShape>
453
469
  <bpmndi:BPMNShape id="BPMNShape_record-merge-dep" bpmnElement="record-merge-dep">
454
- <dc:Bounds x="1388" y="1040" width="100" height="80" />
470
+ <dc:Bounds x="1438" y="720" width="100" height="80" />
471
+ </bpmndi:BPMNShape>
472
+ <bpmndi:BPMNShape id="BPMNShape_be_fixci_sla" bpmnElement="be_fixci_sla">
473
+ <dc:Bounds x="1070" y="622" width="36" height="36" />
474
+ <bpmndi:BPMNLabel>
475
+ <dc:Bounds x="1046" y="703" width="84" height="14" />
476
+ </bpmndi:BPMNLabel>
477
+ </bpmndi:BPMNShape>
478
+ <bpmndi:BPMNShape id="BPMNShape_be_rebase_sla" bpmnElement="be_rebase_sla">
479
+ <dc:Bounds x="1070" y="942" width="36" height="36" />
480
+ <bpmndi:BPMNLabel>
481
+ <dc:Bounds x="1046" y="1043" width="84" height="14" />
482
+ </bpmndi:BPMNLabel>
455
483
  </bpmndi:BPMNShape>
456
484
  <bpmndi:BPMNEdge id="BPMNEdge_f_m_start" bpmnElement="f_m_start">
457
485
  <di:waypoint x="116" y="120" />
@@ -482,74 +510,83 @@
482
510
  </bpmndi:BPMNEdge>
483
511
  <bpmndi:BPMNEdge id="BPMNEdge_f_m_gMerged" bpmnElement="f_m_gMerged">
484
512
  <di:waypoint x="1113" y="120" />
485
- <di:waypoint x="1588" y="120" />
513
+ <di:waypoint x="1638" y="120" />
486
514
  <bpmndi:BPMNLabel>
487
- <dc:Bounds x="1326" y="98" width="49" height="14" />
515
+ <dc:Bounds x="1351" y="98" width="49" height="14" />
488
516
  </bpmndi:BPMNLabel>
489
517
  </bpmndi:BPMNEdge>
490
518
  <bpmndi:BPMNEdge id="BPMNEdge_f_m_done" bpmnElement="f_m_done">
491
- <di:waypoint x="1688" y="120" />
492
- <di:waypoint x="1788" y="120" />
519
+ <di:waypoint x="1738" y="120" />
520
+ <di:waypoint x="1838" y="120" />
493
521
  </bpmndi:BPMNEdge>
494
522
  <bpmndi:BPMNEdge id="BPMNEdge_f_ci_giveup" bpmnElement="f_ci_giveup">
495
- <di:waypoint x="913" y="760" />
496
- <di:waypoint x="1038" y="760" />
523
+ <di:waypoint x="913" y="1560" />
524
+ <di:waypoint x="1238" y="1560" />
497
525
  <bpmndi:BPMNLabel>
498
- <dc:Bounds x="942" y="765" width="67" height="28" />
526
+ <dc:Bounds x="1032" y="1527" width="67" height="28" />
499
527
  </bpmndi:BPMNLabel>
500
528
  </bpmndi:BPMNEdge>
501
529
  <bpmndi:BPMNEdge id="BPMNEdge_f_ci_reconcile" bpmnElement="f_ci_reconcile">
502
- <di:waypoint x="1263" y="945" />
503
- <di:waypoint x="1263" y="980" />
504
- <di:waypoint x="402" y="980" />
530
+ <di:waypoint x="1288" y="625" />
531
+ <di:waypoint x="1288" y="680" />
532
+ <di:waypoint x="402" y="680" />
505
533
  <di:waypoint x="402" y="160" />
506
534
  <bpmndi:BPMNLabel>
507
- <dc:Bounds x="792" y="919" width="82" height="56" />
535
+ <dc:Bounds x="804" y="619" width="82" height="56" />
508
536
  </bpmndi:BPMNLabel>
509
537
  </bpmndi:BPMNEdge>
510
538
  <bpmndi:BPMNEdge id="BPMNEdge_f_reb_giveup" bpmnElement="f_reb_giveup">
511
539
  <di:waypoint x="913" y="280" />
512
- <di:waypoint x="1088" y="280" />
513
- <di:waypoint x="1088" y="720" />
540
+ <di:waypoint x="933" y="280" />
541
+ <di:waypoint x="933" y="305" />
542
+ <di:waypoint x="1333" y="305" />
543
+ <di:waypoint x="1333" y="1500" />
544
+ <di:waypoint x="1288" y="1500" />
545
+ <di:waypoint x="1288" y="1520" />
514
546
  <bpmndi:BPMNLabel>
515
- <dc:Bounds x="977" y="247" width="67" height="28" />
547
+ <dc:Bounds x="1338" y="1246" width="67" height="28" />
516
548
  </bpmndi:BPMNLabel>
517
549
  </bpmndi:BPMNEdge>
518
550
  <bpmndi:BPMNEdge id="BPMNEdge_f_reb_reconcile" bpmnElement="f_reb_reconcile">
519
- <di:waypoint x="1263" y="1265" />
520
- <di:waypoint x="1263" y="1300" />
521
- <di:waypoint x="402" y="1300" />
551
+ <di:waypoint x="1288" y="945" />
552
+ <di:waypoint x="1288" y="1000" />
553
+ <di:waypoint x="402" y="1000" />
522
554
  <di:waypoint x="402" y="160" />
523
555
  <bpmndi:BPMNLabel>
524
- <dc:Bounds x="792" y="1239" width="82" height="56" />
556
+ <dc:Bounds x="804" y="939" width="82" height="56" />
525
557
  </bpmndi:BPMNLabel>
526
558
  </bpmndi:BPMNEdge>
527
559
  <bpmndi:BPMNEdge id="BPMNEdge_f_eg_landed" bpmnElement="f_eg_landed">
528
- <di:waypoint x="1288" y="280" />
529
- <di:waypoint x="1420" y="280" />
560
+ <di:waypoint x="1313" y="280" />
561
+ <di:waypoint x="1470" y="280" />
530
562
  </bpmndi:BPMNEdge>
531
563
  <bpmndi:BPMNEdge id="BPMNEdge_f_m_landed" bpmnElement="f_m_landed">
532
- <di:waypoint x="1456" y="280" />
533
- <di:waypoint x="1638" y="280" />
534
- <di:waypoint x="1638" y="160" />
564
+ <di:waypoint x="1506" y="280" />
565
+ <di:waypoint x="1688" y="280" />
566
+ <di:waypoint x="1688" y="160" />
535
567
  </bpmndi:BPMNEdge>
536
568
  <bpmndi:BPMNEdge id="BPMNEdge_f_m_escC" bpmnElement="f_m_escC">
537
- <di:waypoint x="1138" y="760" />
538
- <di:waypoint x="1638" y="760" />
539
- <di:waypoint x="1638" y="618" />
569
+ <di:waypoint x="1338" y="1560" />
570
+ <di:waypoint x="1688" y="1560" />
571
+ <di:waypoint x="1688" y="1098" />
540
572
  </bpmndi:BPMNEdge>
541
573
  <bpmndi:BPMNEdge id="BPMNEdge_f_m_answer" bpmnElement="f_m_answer">
542
- <di:waypoint x="1638" y="618" />
543
- <di:waypoint x="1638" y="660" />
544
- <di:waypoint x="402" y="660" />
574
+ <di:waypoint x="1688" y="1098" />
575
+ <di:waypoint x="1688" y="1140" />
576
+ <di:waypoint x="402" y="1140" />
545
577
  <di:waypoint x="402" y="160" />
546
578
  </bpmndi:BPMNEdge>
547
579
  <bpmndi:BPMNEdge id="BPMNEdge_f_m_mCiFix" bpmnElement="f_m_mCiFix">
548
580
  <di:waypoint x="713" y="145" />
549
- <di:waypoint x="713" y="760" />
550
- <di:waypoint x="863" y="760" />
581
+ <di:waypoint x="713" y="318" />
582
+ <di:waypoint x="1358" y="318" />
583
+ <di:waypoint x="1358" y="1020" />
584
+ <di:waypoint x="863" y="1020" />
585
+ <di:waypoint x="863" y="1515" />
586
+ <di:waypoint x="888" y="1515" />
587
+ <di:waypoint x="888" y="1535" />
551
588
  <bpmndi:BPMNLabel>
552
- <dc:Bounds x="718" y="518" width="60" height="42" />
589
+ <dc:Bounds x="971" y="1025" width="60" height="42" />
553
590
  </bpmndi:BPMNLabel>
554
591
  </bpmndi:BPMNEdge>
555
592
  <bpmndi:BPMNEdge id="BPMNEdge_f_m_mRebase" bpmnElement="f_m_mRebase">
@@ -563,137 +600,162 @@
563
600
  <bpmndi:BPMNEdge id="BPMNEdge_f_m_mBlocked" bpmnElement="f_m_mBlocked">
564
601
  <di:waypoint x="713" y="145" />
565
602
  <di:waypoint x="713" y="318" />
566
- <di:waypoint x="1018" y="318" />
567
- <di:waypoint x="1018" y="740" />
568
- <di:waypoint x="1038" y="740" />
603
+ <di:waypoint x="1333" y="318" />
604
+ <di:waypoint x="1333" y="1020" />
605
+ <di:waypoint x="1218" y="1020" />
606
+ <di:waypoint x="1218" y="1540" />
607
+ <di:waypoint x="1238" y="1540" />
569
608
  <bpmndi:BPMNLabel>
570
- <dc:Bounds x="823" y="326" width="85" height="14" />
609
+ <dc:Bounds x="1243" y="702" width="85" height="14" />
571
610
  </bpmndi:BPMNLabel>
572
611
  </bpmndi:BPMNEdge>
573
612
  <bpmndi:BPMNEdge id="BPMNEdge_f_ci_go" bpmnElement="f_ci_go">
574
- <di:waypoint x="888" y="785" />
575
- <di:waypoint x="888" y="920" />
576
- <di:waypoint x="1038" y="920" />
613
+ <di:waypoint x="888" y="1585" />
614
+ <di:waypoint x="888" y="1605" />
615
+ <di:waypoint x="1726" y="1605" />
616
+ <di:waypoint x="1726" y="555" />
617
+ <di:waypoint x="1018" y="555" />
618
+ <di:waypoint x="1018" y="580" />
619
+ <di:waypoint x="1038" y="580" />
577
620
  <bpmndi:BPMNLabel>
578
- <dc:Bounds x="893" y="839" width="49" height="28" />
621
+ <dc:Bounds x="1731" y="1046" width="49" height="28" />
579
622
  </bpmndi:BPMNLabel>
580
623
  </bpmndi:BPMNEdge>
581
624
  <bpmndi:BPMNEdge id="BPMNEdge_f_ci_blocked" bpmnElement="f_ci_blocked">
582
- <di:waypoint x="1288" y="920" />
583
- <di:waypoint x="1308" y="920" />
584
- <di:waypoint x="1308" y="895" />
585
- <di:waypoint x="1676" y="895" />
586
- <di:waypoint x="1676" y="562" />
587
- <di:waypoint x="1488" y="562" />
625
+ <di:waypoint x="1313" y="600" />
626
+ <di:waypoint x="1418" y="600" />
627
+ <di:waypoint x="1418" y="1080" />
628
+ <di:waypoint x="1438" y="1080" />
588
629
  <bpmndi:BPMNLabel>
589
- <dc:Bounds x="1448" y="873" width="89" height="14" />
630
+ <dc:Bounds x="1423" y="863" width="89" height="14" />
590
631
  </bpmndi:BPMNLabel>
591
632
  </bpmndi:BPMNEdge>
592
633
  <bpmndi:BPMNEdge id="BPMNEdge_f_ci_wait" bpmnElement="f_ci_wait">
593
- <di:waypoint x="1263" y="945" />
594
- <di:waypoint x="1263" y="1080" />
595
- <di:waypoint x="1388" y="1080" />
634
+ <di:waypoint x="1313" y="600" />
635
+ <di:waypoint x="1488" y="600" />
636
+ <di:waypoint x="1488" y="720" />
596
637
  <bpmndi:BPMNLabel>
597
- <dc:Bounds x="1268" y="1016" width="75" height="28" />
638
+ <dc:Bounds x="1416" y="567" width="75" height="28" />
598
639
  </bpmndi:BPMNLabel>
599
640
  </bpmndi:BPMNEdge>
600
641
  <bpmndi:BPMNEdge id="BPMNEdge_f_reb_go" bpmnElement="f_reb_go">
601
642
  <di:waypoint x="913" y="280" />
602
643
  <di:waypoint x="933" y="280" />
603
644
  <di:waypoint x="933" y="305" />
604
- <di:waypoint x="1708" y="305" />
605
- <di:waypoint x="1708" y="1140" />
606
- <di:waypoint x="1018" y="1140" />
607
- <di:waypoint x="1018" y="1220" />
608
- <di:waypoint x="1038" y="1220" />
645
+ <di:waypoint x="1558" y="305" />
646
+ <di:waypoint x="1558" y="1500" />
647
+ <di:waypoint x="1418" y="1500" />
648
+ <di:waypoint x="1418" y="875" />
649
+ <di:waypoint x="1018" y="875" />
650
+ <di:waypoint x="1018" y="900" />
651
+ <di:waypoint x="1038" y="900" />
609
652
  <bpmndi:BPMNLabel>
610
- <dc:Bounds x="1713" y="709" width="49" height="28" />
653
+ <dc:Bounds x="1464" y="1467" width="49" height="28" />
611
654
  </bpmndi:BPMNLabel>
612
655
  </bpmndi:BPMNEdge>
613
656
  <bpmndi:BPMNEdge id="BPMNEdge_f_reb_blocked" bpmnElement="f_reb_blocked">
614
- <di:waypoint x="1288" y="1240" />
615
- <di:waypoint x="1308" y="1240" />
616
- <di:waypoint x="1308" y="1215" />
617
- <di:waypoint x="1676" y="1215" />
618
- <di:waypoint x="1676" y="562" />
619
- <di:waypoint x="1488" y="562" />
657
+ <di:waypoint x="1313" y="920" />
658
+ <di:waypoint x="1488" y="920" />
659
+ <di:waypoint x="1488" y="1040" />
620
660
  <bpmndi:BPMNLabel>
621
- <dc:Bounds x="1460" y="1182" width="64" height="28" />
661
+ <dc:Bounds x="1429" y="887" width="64" height="28" />
622
662
  </bpmndi:BPMNLabel>
623
663
  </bpmndi:BPMNEdge>
624
664
  <bpmndi:BPMNEdge id="BPMNEdge_f_reb_wait" bpmnElement="f_reb_wait">
625
- <di:waypoint x="1263" y="1215" />
626
- <di:waypoint x="1263" y="1140" />
627
- <di:waypoint x="1438" y="1140" />
628
- <di:waypoint x="1438" y="1120" />
665
+ <di:waypoint x="1288" y="895" />
666
+ <di:waypoint x="1288" y="760" />
667
+ <di:waypoint x="1438" y="760" />
629
668
  <bpmndi:BPMNLabel>
630
- <dc:Bounds x="1268" y="1164" width="75" height="28" />
669
+ <dc:Bounds x="1208" y="834" width="75" height="28" />
631
670
  </bpmndi:BPMNLabel>
632
671
  </bpmndi:BPMNEdge>
633
672
  <bpmndi:BPMNEdge id="BPMNEdge_f_m_gQueued" bpmnElement="f_m_gQueued">
634
673
  <di:waypoint x="1088" y="145" />
635
674
  <di:waypoint x="1088" y="280" />
636
- <di:waypoint x="1238" y="280" />
675
+ <di:waypoint x="1263" y="280" />
637
676
  <bpmndi:BPMNLabel>
638
677
  <dc:Bounds x="1093" y="206" width="46" height="14" />
639
678
  </bpmndi:BPMNLabel>
640
679
  </bpmndi:BPMNEdge>
641
680
  <bpmndi:BPMNEdge id="BPMNEdge_f_eg_evicted" bpmnElement="f_eg_evicted">
642
- <di:waypoint x="1263" y="305" />
643
- <di:waypoint x="1263" y="440" />
644
- <di:waypoint x="1420" y="440" />
681
+ <di:waypoint x="1288" y="305" />
682
+ <di:waypoint x="1288" y="440" />
683
+ <di:waypoint x="1470" y="440" />
645
684
  </bpmndi:BPMNEdge>
646
685
  <bpmndi:BPMNEdge id="BPMNEdge_f_m_gBlocked" bpmnElement="f_m_gBlocked">
647
686
  <di:waypoint x="1088" y="95" />
648
687
  <di:waypoint x="1088" y="75" />
649
- <di:waypoint x="1844" y="75" />
650
- <di:waypoint x="1844" y="478" />
651
- <di:waypoint x="1368" y="478" />
652
- <di:waypoint x="1368" y="580" />
653
- <di:waypoint x="1388" y="580" />
688
+ <di:waypoint x="1894" y="75" />
689
+ <di:waypoint x="1894" y="820" />
690
+ <di:waypoint x="1418" y="820" />
691
+ <di:waypoint x="1418" y="1060" />
692
+ <di:waypoint x="1438" y="1060" />
654
693
  <bpmndi:BPMNLabel>
655
- <dc:Bounds x="1849" y="270" width="53" height="14" />
694
+ <dc:Bounds x="1899" y="441" width="53" height="14" />
656
695
  </bpmndi:BPMNLabel>
657
696
  </bpmndi:BPMNEdge>
658
697
  <bpmndi:BPMNEdge id="BPMNEdge_f_ci_done" bpmnElement="f_ci_done">
659
- <di:waypoint x="1138" y="920" />
660
- <di:waypoint x="1238" y="920" />
698
+ <di:waypoint x="1138" y="600" />
699
+ <di:waypoint x="1263" y="600" />
661
700
  </bpmndi:BPMNEdge>
662
701
  <bpmndi:BPMNEdge id="BPMNEdge_f_reb_done" bpmnElement="f_reb_done">
663
- <di:waypoint x="1138" y="1240" />
664
- <di:waypoint x="1238" y="1240" />
702
+ <di:waypoint x="1138" y="920" />
703
+ <di:waypoint x="1263" y="920" />
665
704
  </bpmndi:BPMNEdge>
666
705
  <bpmndi:BPMNEdge id="BPMNEdge_f_m_escA" bpmnElement="f_m_escA">
667
- <di:waypoint x="1488" y="600" />
668
- <di:waypoint x="1620" y="600" />
706
+ <di:waypoint x="1538" y="1080" />
707
+ <di:waypoint x="1670" y="1080" />
708
+ </bpmndi:BPMNEdge>
709
+ <bpmndi:BPMNEdge id="BPMNEdge_f_reb_sla" bpmnElement="f_reb_sla">
710
+ <di:waypoint x="1088" y="978" />
711
+ <di:waypoint x="1088" y="998" />
712
+ <di:waypoint x="1218" y="998" />
713
+ <di:waypoint x="1218" y="1560" />
714
+ <di:waypoint x="1238" y="1560" />
715
+ <bpmndi:BPMNLabel>
716
+ <dc:Bounds x="1118" y="965" width="70" height="28" />
717
+ </bpmndi:BPMNLabel>
718
+ </bpmndi:BPMNEdge>
719
+ <bpmndi:BPMNEdge id="BPMNEdge_f_ci_sla" bpmnElement="f_ci_sla">
720
+ <di:waypoint x="1088" y="658" />
721
+ <di:waypoint x="1088" y="678" />
722
+ <di:waypoint x="1018" y="678" />
723
+ <di:waypoint x="1018" y="540" />
724
+ <di:waypoint x="1618" y="540" />
725
+ <di:waypoint x="1618" y="820" />
726
+ <di:waypoint x="1526" y="820" />
727
+ <di:waypoint x="1526" y="1040" />
728
+ <bpmndi:BPMNLabel>
729
+ <dc:Bounds x="1243" y="507" width="70" height="28" />
730
+ </bpmndi:BPMNLabel>
669
731
  </bpmndi:BPMNEdge>
670
732
  <bpmndi:BPMNEdge id="BPMNEdge_f_ci_fixed" bpmnElement="f_ci_fixed">
671
- <di:waypoint x="1263" y="945" />
672
- <di:waypoint x="1263" y="980" />
673
- <di:waypoint x="402" y="980" />
733
+ <di:waypoint x="1288" y="625" />
734
+ <di:waypoint x="1288" y="680" />
735
+ <di:waypoint x="402" y="680" />
674
736
  <di:waypoint x="402" y="160" />
675
737
  <bpmndi:BPMNLabel>
676
- <dc:Bounds x="813" y="988" width="39" height="14" />
738
+ <dc:Bounds x="826" y="688" width="39" height="14" />
677
739
  </bpmndi:BPMNLabel>
678
740
  </bpmndi:BPMNEdge>
679
741
  <bpmndi:BPMNEdge id="BPMNEdge_f_reb_rebased" bpmnElement="f_reb_rebased">
680
- <di:waypoint x="1263" y="1265" />
681
- <di:waypoint x="1263" y="1300" />
682
- <di:waypoint x="402" y="1300" />
742
+ <di:waypoint x="1288" y="945" />
743
+ <di:waypoint x="1288" y="1000" />
744
+ <di:waypoint x="402" y="1000" />
683
745
  <di:waypoint x="402" y="160" />
684
746
  <bpmndi:BPMNLabel>
685
- <dc:Bounds x="806" y="1308" width="53" height="14" />
747
+ <dc:Bounds x="799" y="1008" width="53" height="14" />
686
748
  </bpmndi:BPMNLabel>
687
749
  </bpmndi:BPMNEdge>
688
750
  <bpmndi:BPMNEdge id="BPMNEdge_f_dep_rewait" bpmnElement="f_dep_rewait">
689
- <di:waypoint x="1438" y="1120" />
690
- <di:waypoint x="1438" y="1140" />
691
- <di:waypoint x="234" y="1140" />
751
+ <di:waypoint x="1488" y="800" />
752
+ <di:waypoint x="1488" y="820" />
753
+ <di:waypoint x="234" y="820" />
692
754
  <di:waypoint x="234" y="138" />
693
755
  </bpmndi:BPMNEdge>
694
756
  <bpmndi:BPMNEdge id="BPMNEdge_f_m_evicted" bpmnElement="f_m_evicted">
695
- <di:waypoint x="1438" y="458" />
696
- <di:waypoint x="1438" y="478" />
757
+ <di:waypoint x="1488" y="458" />
758
+ <di:waypoint x="1488" y="478" />
697
759
  <di:waypoint x="402" y="478" />
698
760
  <di:waypoint x="402" y="160" />
699
761
  </bpmndi:BPMNEdge>
@@ -0,0 +1,101 @@
1
+ // pr.converge-gate — the deterministic review-comment gate for the convergence loop.
2
+ //
3
+ // The loop declares convergence on the review-round AGENT's self-reported `status = "converged"`.
4
+ // That trusts the agent to only converge once every Copilot comment is addressed — which failed on
5
+ // Magikcraft/nano-bpm#770 (20 rounds, a suppressed advisory never applied, then auto-merged with
6
+ // the comment unaddressed). This step runs on the converged path, BEFORE pr.finalize hands off to
7
+ // the merge loop, and blocks handoff while GitHub still shows unaddressed comments:
8
+ // • any review THREAD is still unresolved (GraphQL `isResolved = false`), or
9
+ // • any SUPPRESSED advisory in the latest Copilot review body lacks a matching RESOLVED ack
10
+ // thread (a `nano-ack: <path>:<line>` marker copied from Copilot's `**path:line**` header).
11
+ // A blocked gate returns `convergeBlocked = true`; the model's `gw-converge-gate` gateway routes to
12
+ // the human `wait-answer` escalation (recoverable), never a hard wedge.
13
+ //
14
+ // It FAILS CLOSED: if the live GitHub state cannot be read, it blocks (escalates) rather than
15
+ // letting an unverifiable "converged" through — the opposite of the no-progress guard, because a
16
+ // merge-gating check must escalate-on-uncertainty so #770 cannot recur.
17
+ import type { AppJobHandler } from "@nanobpm/urban";
18
+ import { type ConvergeGateResult, evaluateConvergeGate } from "../../app/convergeGate.ts";
19
+ import {
20
+ fetchLatestCopilotReviewBody,
21
+ fetchReviewThreads,
22
+ parseAckedAdvisories,
23
+ parseSuppressedAdvisories,
24
+ type ReviewThread,
25
+ } from "../../app/github.ts";
26
+ import { parsePr } from "../../app/service.ts";
27
+ import type { WorkerInputs, WorkerOutputs } from "../../nano-generated/worker-io.d.ts";
28
+
29
+ // Input/output typed off the model data envelopes (`PrConvergeGateIn` / `PrConvergeGateOut` in
30
+ // convergence-loop.bpmn), the single source of truth for this worker's wire contract (ADR 0040).
31
+ type In = WorkerInputs["pr.converge-gate"];
32
+ type Out = WorkerOutputs["pr.converge-gate"];
33
+
34
+ // Reads a PR's review threads. `null` = no usable transport (treated as an unverifiable read →
35
+ // fail closed). Throws propagate to the fail-closed catch below.
36
+ export type ThreadsReader = (repo: string, prNumber: number) => Promise<ReviewThread[] | null>;
37
+ // Reads the latest Copilot review body. `null` = no usable transport (unverifiable → fail closed);
38
+ // `""` = transport usable but no Copilot review yet (verified: no suppressed advisories).
39
+ export type ReviewBodyReader = (repo: string, prNumber: number) => Promise<string | null>;
40
+
41
+ const defaultReadThreads: ThreadsReader = (repo, prNumber) =>
42
+ fetchReviewThreads(repo, prNumber, process.env.GITHUB_TOKEN ?? "");
43
+ const defaultReadReviewBody: ReviewBodyReader = (repo, prNumber) =>
44
+ fetchLatestCopilotReviewBody(repo, prNumber, process.env.GITHUB_TOKEN ?? "");
45
+
46
+ const BLOCK_UNVERIFIABLE =
47
+ "Convergence blocked: could not verify the PR's review comments against GitHub. A human must confirm every Copilot review thread is resolved and every suppressed advisory acknowledged before this PR converges (reply to resume the loop).";
48
+
49
+ /** Build the handler with injectable GitHub readers. The default export binds the real readers;
50
+ * tests inject stubs. Fails CLOSED — any unreadable/errored state blocks convergence. */
51
+ export function makeHandler(deps: {
52
+ readThreads: ThreadsReader;
53
+ readReviewBody: ReviewBodyReader;
54
+ }): AppJobHandler<In, Out> {
55
+ return async (job) => {
56
+ const { prKey, repo, prNumber } = job.variables;
57
+ // `parsePr` is total on any input (fails closed to `null` on a missing/non-string prKey), so
58
+ // pass it straight through — a malformed prKey degrades to the fail-closed target check below.
59
+ const parsed = parsePr(prKey);
60
+ const ghRepo = repo ?? parsed?.repo;
61
+ const ghNumber = typeof prNumber === "number" ? prNumber : parsed?.number;
62
+ if (!ghRepo || typeof ghNumber !== "number") {
63
+ return { convergeBlocked: true, convergeBlockReason: BLOCK_UNVERIFIABLE };
64
+ }
65
+
66
+ let result: ConvergeGateResult;
67
+ try {
68
+ const threads = await deps.readThreads(ghRepo, ghNumber);
69
+ // A null threads read is an unverifiable gate — fail closed. (An empty ARRAY is a verified
70
+ // "no threads" and is fine.)
71
+ if (threads === null) {
72
+ return { convergeBlocked: true, convergeBlockReason: BLOCK_UNVERIFIABLE };
73
+ }
74
+ const reviewBody = await deps.readReviewBody(ghRepo, ghNumber);
75
+ // A null review body is an unverifiable read (no usable transport) — fail closed, same as a
76
+ // null threads read. (An empty STRING is a verified "no Copilot review / no advisories".)
77
+ if (reviewBody === null) {
78
+ return { convergeBlocked: true, convergeBlockReason: BLOCK_UNVERIFIABLE };
79
+ }
80
+ const unresolvedThreadCount = threads.filter((t) => !t.isResolved).length;
81
+ result = evaluateConvergeGate({
82
+ unresolvedThreadCount,
83
+ suppressedKeys: parseSuppressedAdvisories(reviewBody),
84
+ acknowledgedKeys: parseAckedAdvisories(threads),
85
+ });
86
+ } catch {
87
+ return { convergeBlocked: true, convergeBlockReason: BLOCK_UNVERIFIABLE };
88
+ }
89
+
90
+ return {
91
+ convergeBlocked: result.convergeBlocked,
92
+ convergeBlockReason: result.convergeBlockReason,
93
+ };
94
+ };
95
+ }
96
+
97
+ const handler = makeHandler({
98
+ readThreads: defaultReadThreads,
99
+ readReviewBody: defaultReadReviewBody,
100
+ });
101
+ export default handler;