@g1cloud/bpmn-modeler-next 5.0.0-alpha.8 → 5.0.0-alpha.80
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/dist/agent/describeProcess.d.ts +14 -3
- package/dist/agent/geometryAudit.d.ts +436 -3
- package/dist/agent/resolver/index.d.ts +27 -1
- package/dist/agent/resolver/issues.d.ts +12 -0
- package/dist/agent/resolver/lower.d.ts +86 -0
- package/dist/agent/resolver/routeRepair.d.ts +215 -5
- package/dist/agent/symbolicOp.d.ts +11 -4
- package/dist/bpmn-modeler.js +11918 -9533
- package/dist/bpmn-modeler.umd.cjs +86 -85
- package/dist/core/hints.d.ts +28 -0
- package/dist/core/ir.d.ts +32 -6
- package/package.json +2 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ModdleElement, ParseWarning } from '../adapter/xml';
|
|
2
|
-
import { BwlBand, BwlPlacement, BwlPoolOrder } from '../core/hints';
|
|
2
|
+
import { BwlAfterColumn, BwlBand, BwlPlacement, BwlPoolOrder } from '../core/hints';
|
|
3
3
|
import { IrDefinition } from '../core/ir';
|
|
4
4
|
/** 파생 뷰가 표현하지 못한 요소 — 침묵 폐기 금지(에이전트가 미표현 존재를 알아야 안전). */
|
|
5
5
|
export interface IrOmission {
|
|
@@ -7,8 +7,14 @@ export interface IrOmission {
|
|
|
7
7
|
/** bpmn $type 원형 (예: `bpmn:BoundaryEvent`) */
|
|
8
8
|
type: string;
|
|
9
9
|
reason:
|
|
10
|
-
/**
|
|
10
|
+
/** IR 타입 집합 밖 (intermediate 이벤트·dataObject 등 — 승격 시 자동 해소) */
|
|
11
11
|
'type-outside-mvp'
|
|
12
|
+
/**
|
|
13
|
+
* 승격된 컨테이너(subProcess) **내부**라 표현하지 않음 (B-87 ⓐ = 불투명 승격).
|
|
14
|
+
* 컨테이너 자신은 노드로 보이지만 내부는 열지 않았다 — 침묵하면 에이전트가 빈 컨테이너로
|
|
15
|
+
* 오인해 파괴적 편집을 한다. 내부를 IR 에 내려면 부모 채널·컨테이너 내부 좌표계가 필요하다.
|
|
16
|
+
*/
|
|
17
|
+
| 'inside-container'
|
|
12
18
|
/** 끝점이 미표현 요소라 연결 자체를 표현할 수 없음 */
|
|
13
19
|
| 'endpoint-outside-mvp'
|
|
14
20
|
/** 협업 문서인데 어느 participant 도 참조하지 않는 프로세스 (풀 귀속 불명) */
|
|
@@ -21,8 +27,13 @@ export interface IrOmission {
|
|
|
21
27
|
export interface BwlHintView {
|
|
22
28
|
/** participant id → 풀 세로 순서 */
|
|
23
29
|
poolOrders: Record<string, BwlPoolOrder>;
|
|
24
|
-
/** 플로우 노드 id → 프로세스 내부 가로 밴드 */
|
|
30
|
+
/** 플로우 노드 id → 프로세스 내부 가로 밴드(행) */
|
|
25
31
|
bands: Record<string, BwlBand>;
|
|
32
|
+
/**
|
|
33
|
+
* 플로우 노드 id → 열 지목 힌트(그 노드보다 뒤 열). `bands` 와 대칭 채널이다.
|
|
34
|
+
* ⚠ **존재 필터**(A-6) — 참조 대상이 문서에 없으면 내지 않는다(힌트 = 파생 정보 · 불변식 2).
|
|
35
|
+
*/
|
|
36
|
+
afterColumns: Record<string, BwlAfterColumn>;
|
|
26
37
|
/** 주석 id → 앵커 기준 방위 (앵커 부재분은 필터됨) */
|
|
27
38
|
placements: Record<string, BwlPlacement>;
|
|
28
39
|
}
|
|
@@ -22,6 +22,24 @@ export interface GeometryShape {
|
|
|
22
22
|
* 판정의 근거: 노드가 자기 풀 밖에 그려져 있으면 좌표만 보는 사람은 **남의 풀 노드로 읽는다.**
|
|
23
23
|
*/
|
|
24
24
|
parent?: string;
|
|
25
|
+
/**
|
|
26
|
+
* 도형의 **외부 이름 라벨** bounds(이벤트·게이트웨이의 이름은 도형 밖에 그려진다 — 있을 때만).
|
|
27
|
+
* `annotation-over-label` 의 입력(B-24 ⓑ): 주석 상자가 이 위에 놓이면 텍스트가 겹쳐 둘 다 읽을 수 없다.
|
|
28
|
+
*
|
|
29
|
+
* ⚠ **블랙박스 풀은 예외적으로 "움직일 수 없는" 라벨을 갖는다**(B-38) — `processRef` 없는 참여자는
|
|
30
|
+
* bpmn-js 가 이름을 풀 **본체 중앙에 가로로** 그리고(`isExpanded` = `!!processRef` → 렌더러 else 분기,
|
|
31
|
+
* `align: 'center-middle'`), 그 좌표는 DI 에 `BPMNLabel` 로 남지 않는 **렌더 산물**이다. 위치가 폭의
|
|
32
|
+
* 함수라 라벨을 옮겨서는 못 고치고 **풀 기하를 바꿔야** 한다. 라벨을 이동시키는 보정
|
|
33
|
+
* (`repairIntroducedShapeLabelLines`)은 `container` 로 이미 걸러진다.
|
|
34
|
+
*/
|
|
35
|
+
label?: GeometryLabel;
|
|
36
|
+
/**
|
|
37
|
+
* 그룹의 멤버 id 목록(`bwl:members` 힌트, A-4 — 그룹일 때만). `group-overlap-unintended` 의 입력:
|
|
38
|
+
* 두 그룹의 바운즈가 겹칠 때 **멤버를 공유하면 의도된 겹침**(한 노드가 두 단계에 걸친다)이고,
|
|
39
|
+
* 공유하지 않으면 **그리다 보니 겹친 것**이다. 힌트가 없는 그룹(사람이 GUI 로 그린 것)은 판단할
|
|
40
|
+
* 근거가 없으므로 판정하지 않는다.
|
|
41
|
+
*/
|
|
42
|
+
members?: readonly string[];
|
|
25
43
|
}
|
|
26
44
|
/** 간선 외부 라벨의 bounds — 라벨은 판정 대상 도형이 아니지만 **어느 간선의 것으로 읽히는가**는 판정한다(B-15). */
|
|
27
45
|
export interface GeometryLabel {
|
|
@@ -36,6 +54,16 @@ export interface GeometryEdge {
|
|
|
36
54
|
waypoints: GeometryPoint[];
|
|
37
55
|
/** 이 간선이 자기 끝점으로 삼는 도형 id 들 — 그 도형과의 교차는 도킹이라 관통이 아니다. */
|
|
38
56
|
endpoints: readonly string[];
|
|
57
|
+
/**
|
|
58
|
+
* 방향 있는 끝점 — `'throughpass'`(B-63) 의 입력. ⚠ **`endpoints` 로 대신할 수 없다**: 두 생성
|
|
59
|
+
* 경로 모두 `[source, target]` 순으로 담지만 falsy 를 걸러내므로 한쪽이 없으면 남은 하나가
|
|
60
|
+
* `[0]` 으로 올라와 **방향이 뒤바뀐다**. 관통은 유입·유출을 가르는 술어라 방향을 틀리면
|
|
61
|
+
* 표본 50(유입 0 = 눌러앉음)과 표본 51(유입 2 = 지나감)의 판정이 뒤집힌다.
|
|
62
|
+
*
|
|
63
|
+
* 둘 다 있을 때만 관통 판정의 입력이 된다(없으면 침묵 — 오탐보다 침묵).
|
|
64
|
+
*/
|
|
65
|
+
source?: string;
|
|
66
|
+
target?: string;
|
|
39
67
|
/** 이름이 있는 간선의 외부 라벨 bounds(있을 때만). `label-on-shared-segment` 의 입력. */
|
|
40
68
|
label?: GeometryLabel;
|
|
41
69
|
}
|
|
@@ -87,6 +115,37 @@ export type GeometryFinding =
|
|
|
87
115
|
axis: 'h' | 'v';
|
|
88
116
|
length: number;
|
|
89
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* 두 간선의 축 정렬 구간이 같은 선 위에 **같은 방향으로** 겹치는데 **종류가 다르다**(실선 시퀀스 ×
|
|
120
|
+
* 점선 메시지 · 점선 연관) — 일곱 번째 표본에서 사용자가 지목: "같은 화살표 방향이면 겹쳐도 좋지만
|
|
121
|
+
* 다른 종류(실선/점선)가 겹치면 가독성을 해친다". 같은 종류·같은 방향(합류·팬아웃)은 여전히 제외.
|
|
122
|
+
* 전형 = 되돌아가는 시퀀스가 목표 아랫면 중심으로 들어오는 열에 메시지플로우도 중심 도킹하는 것.
|
|
123
|
+
*/
|
|
124
|
+
| {
|
|
125
|
+
kind: 'edge-overlap-mixed';
|
|
126
|
+
edges: [string, string];
|
|
127
|
+
axis: 'h' | 'v';
|
|
128
|
+
length: number;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* 두 간선이 같은 선 위를 **같은 방향·같은 종류**로 겹쳐 흐르는데 **끝점을 하나도 공유하지 않는다**
|
|
132
|
+
* (B-77) — 한 선으로 합쳐 보이는데 실은 만난 적이 없고, 공유 구간 끝에서 서로 다른 곳으로 갈라진다.
|
|
133
|
+
* 사용자 증언(재하강 대조, 2026-09-18): *"…본인확인수신에서 나온 선에 합류한다음에 결제실패 종료와
|
|
134
|
+
* 재고할당요청으로 들어가는데 이해가 안되는 상황"*.
|
|
135
|
+
*
|
|
136
|
+
* 🔴 **일곱 번째 표본의 "같은 방향이면 겹쳐도 좋다" 와 모순이 아니다 — 대상이 다르다.** 그때 수용한
|
|
137
|
+
* 것은 **진짜 합류·팬아웃**(소스 또는 타깃을 공유)이고 여기서 잡는 것은 **가짜 합류**다. 판별자는
|
|
138
|
+
* 길이가 아니라 **관계**다(🔁 「양이 안 가르면 대상을 갈라라」). 사람 실무 코퍼스 26종 기저 **0건**.
|
|
139
|
+
*
|
|
140
|
+
* ⚠ **양쪽 `source`·`target` 이 다 알려졌을 때만 판정한다** — 하나라도 모르면 합류와 가를 수 없으므로
|
|
141
|
+
* 침묵한다(오탐보다 침묵 · `throughpass` 와 같은 정책).
|
|
142
|
+
*/
|
|
143
|
+
| {
|
|
144
|
+
kind: 'edge-overlap-unrelated';
|
|
145
|
+
edges: [string, string];
|
|
146
|
+
axis: 'h' | 'v';
|
|
147
|
+
length: number;
|
|
148
|
+
}
|
|
90
149
|
/**
|
|
91
150
|
* 간선의 **라벨이 다른 간선과 공유하는 구간 위**에 놓여 어느 간선의 라벨인지 읽을 수 없다(확정 6
|
|
92
151
|
* 다섯 번째 표본에서 사용자가 지목: "겹치는 선상에 있는 분기 문구가 어느 선에 해당하는지 애매").
|
|
@@ -101,9 +160,317 @@ export type GeometryFinding =
|
|
|
101
160
|
edge: string;
|
|
102
161
|
other: string;
|
|
103
162
|
axis: 'h' | 'v';
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* 간선 라벨의 상자를 **선이 가로지른다** — 자기 간선(또는 다른 간선)의 축 정렬 구간이 상자 안을 지나거나,
|
|
166
|
+
* 컨테이너(레인·풀) 경계선이 상자를 가른다(열세 번째 표본에서 사용자가 지목: "선에 달린 글자가 선과 겹치거나
|
|
167
|
+
* 레인선상에 걸린다"). 전형 = 세로 2점 메시지플로우의 라벨 — bpmn-js 는 라벨 **중심**을 선 + 15 에 두므로 폭 42
|
|
168
|
+
* 라벨은 6px, 폭 64 는 17px 선 위에 걸친다. 가로 구간의 라벨(중심이 선 위 15, 높이 14)은 걸치지 않는다.
|
|
169
|
+
* `line` = 그 간선 id 또는 컨테이너 id. **`edge` = 라벨의 소유자 id** — 간선 라벨이면 간선, **도형의 외부 이름 라벨**
|
|
170
|
+
* (게이트웨이·이벤트 이름, B-29)이면 그 도형 id(스물네 번째 표본: 되돌아가는 간선 가로선이 게이트웨이 이름 라벨을
|
|
171
|
+
* 가로질러 사용자가 세 회차 연속 라벨을 올렸다 — bpmn-js 적응 배치는 도킹 면만 보고 지나가는 선은 안 본다).
|
|
172
|
+
*/
|
|
173
|
+
| {
|
|
174
|
+
kind: 'label-over-line';
|
|
175
|
+
edge: string;
|
|
176
|
+
line: string;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* 텍스트 주석 상자가 다른 요소의 **외부 라벨**(게이트웨이·이벤트 이름, 간선 라벨) 위에 놓였다 — 두 텍스트가
|
|
180
|
+
* 겹쳐 어느 쪽도 읽을 수 없다(열여덟 번째 표본: `top` 주석이 `처리 결과?` 게이트웨이의 이름 라벨을 덮었고
|
|
181
|
+
* 사용자는 "라벨과 코멘트가 비슷한 위치" 라며 주석을 옆으로 옮겼다). 주석 배치가 도형·간선 구간만 피하고
|
|
182
|
+
* 라벨은 보지 않던 공백. `label` = 그 라벨을 소유한 요소 id(도형 또는 간선).
|
|
183
|
+
*/
|
|
184
|
+
| {
|
|
185
|
+
kind: 'annotation-over-label';
|
|
186
|
+
annotation: string;
|
|
187
|
+
label: string;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* 두 그룹의 바운즈가 겹치는데 **멤버를 하나도 공유하지 않는다** — 사람은 그 겹침이 업무적 판단인지
|
|
191
|
+
* (한 활동이 두 단계에 걸친다) 그리다 보니 생긴 것인지 구분할 수 없다(G12 실측에서 사용자가 지목:
|
|
192
|
+
* "그룹이 겹쳐서 판단에 의한 건지 그리다 보니 겹친 건지 판단이 잘 안 되는 상태"). 멤버를 공유하는
|
|
193
|
+
* 겹침은 **의도로 읽히므로 제외**한다 — 겹침 자체가 결함이 아니라 *의도가 표현되지 않은 겹침*이 결함이다.
|
|
194
|
+
* 전형 = 단계 그룹은 x 구간인데 멤버가 여러 풀에 흩어져 x 범위가 서로 물리는 경우(A-4 멤버 bbox 의
|
|
195
|
+
* 구조적 한계). `groups` = 겹친 두 그룹(id 오름차순).
|
|
196
|
+
*/
|
|
197
|
+
| {
|
|
198
|
+
kind: 'group-overlap-unintended';
|
|
199
|
+
groups: [string, string];
|
|
200
|
+
/**
|
|
201
|
+
* 한쪽 상자가 다른 쪽을 **완전히 감쌀 때만** 존재하는 바깥 그룹의 id(B-52). 같은 kind 안에서
|
|
202
|
+
* *부수 겹침*과 *삼킴*은 심각도가 다르다 — 표본 44 에서 사용자가 `Grp_return` 이 `Grp_settle`
|
|
203
|
+
* 을 통째로 덮은 것을 보고 **"정산까지 잡아먹고 있어서 근본적으로 고쳐야 한다"** 고 했고, 그것은
|
|
204
|
+
* 이 계보에서 가장 센 표현이다(다른 회차는 "인지하기 어렵다"·"이해 가능한 범위").
|
|
205
|
+
*
|
|
206
|
+
* 🔴 **id 가 아니라 `true` 를 주면 에이전트가 행동할 수 없다** — `groups` 는 id 오름차순이라
|
|
207
|
+
* 순서가 어느 쪽이 삼켰는지 말하지 않는다. 해소 수단(바깥 그룹의 멤버를 좁힌다)은 **대상을
|
|
208
|
+
* 지목해야** 실행된다.
|
|
209
|
+
*
|
|
210
|
+
* 🔴 **임계를 두지 않는다** — 이 축에서 「양」으로 가르려는 시도는 세 번 기각됐다(겹침 비율 ·
|
|
211
|
+
* `R_box − R_mem` gap · 남의 멤버 개수). 판별자는 양이 아니라 **포함이라는 관계**다.
|
|
212
|
+
*/
|
|
213
|
+
container?: string;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* 두 그룹이 겹치면서 멤버를 공유해 **겹침 자체는 의도로 읽히는데**(그래서 `group-overlap-unintended`
|
|
217
|
+
* 가 침묵한다), 그 겹친 영역 안에 **어느 그룹의 멤버도 아닌 흐름 노드**가 놓여 있다(B-60). 공유 멤버는
|
|
218
|
+
* *두 상자의 관계*만 설명할 뿐 **영역 안 제3의 노드가 어느 단계인지는 말하지 않는다** — 사람은 그
|
|
219
|
+
* 노드를 읽을 근거가 없다. 표본 47 에서 사용자가 **손대지도 않고 포기**했다("그룹겹침은 여전해서
|
|
220
|
+
* 수정할 품이 많이 들어갈것 같아").
|
|
221
|
+
*
|
|
222
|
+
* 🔴 **비율로 가르지 말 것** — B-52 에서 실측 기각됐다(표본 32 에서 사용자가 **72%** 겹침을 그대로
|
|
223
|
+
* 저장했고, 포기한 표본 44·47 은 **70%** 다). 판별자는 비율이 아니라 **영역 안에 든 무소속 노드**다:
|
|
224
|
+
* 수용된 72% 케이스는 영역 안 5개가 **전부 어느 그룹의 멤버**였다(무소속 0).
|
|
225
|
+
*
|
|
226
|
+
* 근거(오탐): 실무 16문서에는 멤버 공유 겹침 쌍 자체가 **0**. 사용자 저장본 36종의 침묵 쌍 24 중
|
|
227
|
+
* **1건**, fixture 48종의 침묵 쌍 30 중 **2건**이고 그 3건이 전부 **사용자가 포기한 회차**(표본 44·45)의
|
|
228
|
+
* 산출물이다. 수용된 49쌍은 **전량 무소속 0**.
|
|
229
|
+
*
|
|
230
|
+
* `groups` = 겹친 두 그룹(id 오름차순) · `shapes` = 영역 안의 무소속 흐름 노드(id 오름차순).
|
|
231
|
+
*/
|
|
232
|
+
| {
|
|
233
|
+
kind: 'group-overlap-unreadable';
|
|
234
|
+
reason: 'orphan';
|
|
235
|
+
groups: [string, string];
|
|
236
|
+
shapes: string[];
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* 한 그룹 상자 안에서 **자기 멤버가 과반이 아니다**(B-62) — 상자 안 흐름 노드의 절반 이상이
|
|
240
|
+
* *남의 그룹 멤버이거나 무소속*이라 사람은 그 상자가 무슨 단계인지 읽을 근거를 잃는다. 표본 50
|
|
241
|
+
* 에서 사용자가 지목하고 포기했다("배송그룹에 에 반품이 포함되어있는게 좀 이상한것 같아서
|
|
242
|
+
* 확인해야 수정할 수 있을것 같아") — 실측 = `Grp_deliver` 안 18 = 자기 8 · **남의 8** · 무소속 2.
|
|
243
|
+
*
|
|
244
|
+
* 🔴 **같은 kind 안의 다른 축이다 — `reason` 으로 가른다.** `'orphan'` 은 *두 상자의 겹침 영역*에
|
|
245
|
+
* 갇힌 **무소속**을 세고(B-60), 이쪽은 *상자 하나 전체*에서 **비자기**를 센다. 표본 50 이 둘을
|
|
246
|
+
* 갈랐다: `'orphan'` 축은 그 상자에서 **무소속 2 만** 보고했는데 사람이 본 것은 **남의 멤버 8**
|
|
247
|
+
* 이었다(§0 ③ — 술어가 짚는 자리는 맞았고 *세는 것*이 틀렸다).
|
|
248
|
+
*
|
|
249
|
+
* 🔴 **비율로 가르지 말 것 — 네 번 기각됐다.** 「남의 멤버 개수 ≥ K」는 표본 32(사용자 **수용**)를
|
|
250
|
+
* 오탐하고(남의 4), 「공유 ≥ 단독」 순수 기하도 같은 케이스를 오탐한다. 판별자는 개수도 겹침
|
|
251
|
+
* 비율도 아니라 **자기 단계가 그 상자에서 과반인가**다 — 50% 는 고른 임계가 아니라 판독의 정의다.
|
|
252
|
+
*
|
|
253
|
+
* 근거(오탐): 실무 16문서 **0**(레거시라 `bwl:members` 가 0건 = 술어의 입력이 없다 → 멤버 미선언
|
|
254
|
+
* 그룹은 제외한다). 사용자 저장본 57종의 그룹 116개 중 **4건**, fixture 56종의 그룹 165개 중
|
|
255
|
+
* **6건**이고 **전부 사용자가 포기한 회차**(표본 44·47·49·50)의 산출물이다. 수용 회차(표본 32·48)는
|
|
256
|
+
* 전량 침묵.
|
|
257
|
+
*
|
|
258
|
+
* ⚠ **`'orphan'` 축의 처방이 이 축을 끈다** — 무소속을 멤버에 넣으면(B-60 의 대가 0 수단) 자기가
|
|
259
|
+
* 늘어 과반이 회복된다. 그러나 **남의 멤버를 자기 것으로 만드는 것은 의미를 훼손한다**(표본 50 에서
|
|
260
|
+
* 에이전트가 *"그림이 거짓말을 하게 된다"* 며 스스로 거부했다). 수단은 단계 경계를 다시 잡는 것이다.
|
|
261
|
+
*
|
|
262
|
+
* `group` = 그 상자 · `shapes` = 상자 안의 비자기 흐름 노드(남의 멤버 + 무소속 · id 오름차순).
|
|
263
|
+
*/
|
|
264
|
+
| {
|
|
265
|
+
kind: 'group-overlap-unreadable';
|
|
266
|
+
reason: 'minority';
|
|
267
|
+
group: string;
|
|
268
|
+
shapes: string[];
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* 다른 단계의 흐름이 이 상자를 **지나간다**(B-63) — 상자 안에 든 *남의 그룹 멤버*로 시퀀스가
|
|
272
|
+
* 밖에서 들어와(유입 ≥1) 밖으로 나간다(유출 ≥1). 사람은 상자가 어디서 끝나는지 읽을 수 없다.
|
|
273
|
+
* 표본 51 에서 사용자가 지목하고 포기했다("입고예정일안내 → 입고대기종료 에 이르는 노테이션이
|
|
274
|
+
* 배송 그룹에 일부 속해서 **관통**하는데 속하지 않을것 같다") — 증언의 단어가 그대로 술어다.
|
|
275
|
+
*
|
|
276
|
+
* 🔴 **`'minority'` 와 상보다 — 상위집합이 아니다.** 같은 `Grp_deliver` 인데 형상이 정반대였다:
|
|
277
|
+
* 표본 50 은 남의 멤버 8 이 들어있지만 **유입 0**(반품 체인의 `Start_ret_cs` 가 상자 안에 있다
|
|
278
|
+
* = 밖에서 들어오지 않고 **눌러앉았다**) 이고, 표본 51 은 유입 2 · 유출 3 으로 **지나간다**.
|
|
279
|
+
* 사용자 증언의 단어도 갈렸다 — 표본 50 *"반품이 **포함**되어있는게"* vs 표본 51 *"**관통**하는데"*.
|
|
280
|
+
* ⇒ `'minority'` 는 **양**(들어앉은 정도)을, 이 축은 **위상**(지나감)을 잰다. 각각이 잡는 회차가
|
|
281
|
+
* 다르고 합쳐야 포기 6회차를 덮는다.
|
|
282
|
+
*
|
|
283
|
+
* 🔴 **무소속을 세지 말 것 — 세면 술어가 `'minority'` 의 상위집합이 되어 얼굴이 중복된다.**
|
|
284
|
+
* N20 실측: 「비자기(남의 멤버 + 무소속) 관통」으로 재면 `'minority'` 발화가 **전부 포함**되고
|
|
285
|
+
* (저장본·fixture 양쪽에서 "minority 만" = 0) 기저가 **17~20%** 로 뛴다. 무소속 게이트웨이 하나가
|
|
286
|
+
* 지나가는 형상(`Grp_intake` — 저장본에서 **다섯 회차 반복**)이 전량 오탐으로 들어오기 때문이다.
|
|
287
|
+
* 사용자가 지목한 것은 *"일부 **속해서**"* = 남의 멤버다.
|
|
288
|
+
*
|
|
289
|
+
* ⚠ **단일 노드 통과는 세지 않는다**(`foreign → foreign` 간선 ≥1 요구) — 노드 하나가 지나가는
|
|
290
|
+
* 것은 "경계에 걸친 것" 으로 읽히고, 여러 노드가 이어져 들어앉아야 "다른 단계가 들어와 있다" 로
|
|
291
|
+
* 읽힌다. 위상 조건이지 임계가 아니다(≥2 = "단일이 아니다"). 검정 성적은 이 조건 유무와 같고
|
|
292
|
+
* 기저만 6.5% → 4.1% 로 내려간다.
|
|
293
|
+
*
|
|
294
|
+
* 🔴 **판별자로 「양」을 재지 말 것 — 다섯 번 무너졌다**(개수 · 비율 72%수용/70%포기 · gap ·
|
|
295
|
+
* 순수기하 · 과반). 이 축은 위상이라 고를 숫자가 없다.
|
|
296
|
+
*
|
|
297
|
+
* 근거(오탐): 실무 16문서 **0**(레거시는 `bwl:members` 0건 = 술어의 입력이 없다). 저장본 58종의
|
|
298
|
+
* 그룹 123개 중 **5건**, fixture 58종의 그룹 178개 중 **10건**이고 **전부 사용자가 포기한 회차**
|
|
299
|
+
* (표본 44·46·47·49·51)의 산출물이다. 수용 회차는 전량 침묵 — 표본 32(`g12-v4` = 남의 4 가
|
|
300
|
+
* 있지만 유입 0·유출 0 인 **완결 체인**이라 귀속이 모호하지 않다 · **N66 통과**)와 표본 48.
|
|
301
|
+
* 놓치는 두 회차도 정합하다 — 표본 50 은 `'minority'` 가 잡고, 표본 45 는 근인이 면 과점유(B-55)다.
|
|
302
|
+
*
|
|
303
|
+
* `group` = 그 상자 · `shapes` = 상자를 지나가는 남의 멤버(id 오름차순).
|
|
304
|
+
*/
|
|
305
|
+
| {
|
|
306
|
+
kind: 'group-overlap-unreadable';
|
|
307
|
+
reason: 'throughpass';
|
|
308
|
+
group: string;
|
|
309
|
+
shapes: string[];
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* **세 그룹 이상이 한 영역을 동시에 덮는다**(B-59) — 그 영역 안의 도형은 세 단계에 한꺼번에 속한
|
|
313
|
+
* 것처럼 보여 어느 단계인지 읽을 수 없다. 표본 46 에서 사용자가 지목했다("그룹 중첩이 많아서
|
|
314
|
+
* 인지하기가 어려워서야 출고/검수/배송이 중첩이라서 … 내가 의도를 에이전트한테 물어봐야하는
|
|
315
|
+
* 상황일것 같아") 그리고 표본 49 에서 다시 포기했다("완전히 겹치던지 안겹치던지 하는게 맞을것
|
|
316
|
+
* 같은데 의도 파악이 안되는 상황이야").
|
|
317
|
+
*
|
|
318
|
+
* 🔴 **`group-overlap-unreadable`(B-60)이 이 형상을 못 잡는다 — 상보적이다.** 근인은 B-32 ⓑ 의
|
|
319
|
+
* "멤버 교집합 ≥1 = 의도" 술어가 **인접 단계 그룹에 대해 항상 참**이라는 것이다. 연속한 단계가
|
|
320
|
+
* 경계 노드를 공유하는 것은 정상이므로(출고의 끝 = 배송의 시작) 세 쌍 중 둘이 공유 멤버 한 개로
|
|
321
|
+
* 침묵하고, 그 침묵한 쌍들이 **한 영역에서 만난다**. B-60 은 영역 안에 **무소속** 노드를 요구하는데
|
|
322
|
+
* 3중 영역의 도형은 대개 어느 한 그룹의 멤버다(표본 46 = 안 5 · 무소속 0 · 표본 49 = 안 2 · 무소속 0).
|
|
323
|
+
*
|
|
324
|
+
* ⚠ **대응이 B-60 과 정반대다** — B-60 은 무소속 노드를 멤버에 넣으면 풀리지만(대가 0), 3중은
|
|
325
|
+
* 멤버를 넓히면 상자가 커져 **더 겹친다**. 표본 49 가 그 예다: 에이전트가 `group.update` 로 멤버
|
|
326
|
+
* 하나를 선제 공유해 판정을 껐고 3중이 남았다. 수단은 단계 경계를 다시 잡는 것(그룹을 줄이거나 합치기)이다.
|
|
327
|
+
*
|
|
328
|
+
* 🔴 **비율로 가르지 말 것** — B-52 에서 두 번 기각됐다(표본 32 **72% 수용** · 표본 47 **70% 포기**).
|
|
329
|
+
* 「상자 겹침도 − 멤버 겹침도」 괴리도 **N20 에서 기각**됐다(수용한 표본 32 가 59.3%p 로 포기한
|
|
330
|
+
* 표본 49 의 59.1%p 보다 **높다**). 판별자는 비율이 아니라 **중복도**다.
|
|
331
|
+
*
|
|
332
|
+
* 근거(오탐): 실무 16문서 **0**(그룹 15) · 저장본 56종 **2**(`g16-base`·`g19-base`) · fixture 53종
|
|
333
|
+
* **3**(전부 `g16-edit*`). **해당 5건이 전부 사용자가 포기한 회차(표본 46·49)의 산출물이고 수용된
|
|
334
|
+
* 회차는 전량 0** 이다. B-60 과 합치면 포기 4회차(표본 44·46·47·49)를 전량 잡고 수용 2회차를
|
|
335
|
+
* 전량 통과시킨다.
|
|
336
|
+
*
|
|
337
|
+
* `groups` = 그 영역을 덮은 세 그룹(id 오름차순) · `shapes` = 영역 안의 흐름 노드(멤버 여부 무관).
|
|
338
|
+
*/
|
|
339
|
+
| {
|
|
340
|
+
kind: 'group-stack-unreadable';
|
|
341
|
+
groups: [string, string, string];
|
|
342
|
+
shapes: string[];
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* 그룹의 테두리가 컨테이너(풀·확장 서브프로세스) 경계선과 **한 선으로 그려진다** — 두 선이 겹쳐
|
|
346
|
+
* 그룹 영역이 풀 테두리와 구분되지 않는다(표본 30 에서 사용자가 지목: "그룹이 레인선에 겹쳐서
|
|
347
|
+
* 출력되는 부분"). 배치 경로에서는 **결정적으로 발생**했다: 풀 상단에서 band 0 노드 중심까지 80,
|
|
348
|
+
* 노드 높이 80 이라 노드 상단 = 풀 상단 + 40 인데 그룹 패딩도 40 이라 정확히 얹힌다(그룹 5/5).
|
|
349
|
+
* 실무 문서에서는 그룹 24개 중 2개(8%)만 이 상태라 사람도 대개 떼어 놓는다. `container` = 그 컨테이너,
|
|
350
|
+
* `side` = 겹친 변.
|
|
351
|
+
*/
|
|
352
|
+
| {
|
|
353
|
+
kind: 'group-on-container-boundary';
|
|
354
|
+
group: string;
|
|
355
|
+
container: string;
|
|
356
|
+
side: 'top' | 'bottom' | 'left' | 'right';
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* **두 그룹의 테두리가 한 선으로 그려진다**(B-45) — 단계 그룹이 옆으로 늘어설 때 결정적으로 난다:
|
|
360
|
+
* 상자 = 멤버 bbox ± 패딩(40) 이라 두 단계의 멤버가 정확히 **80**(= 2 × 패딩) 떨어지면 두 테두리가
|
|
361
|
+
* 정확히 겹친다. 표본 38 에서 사용자가 지목("그룹간에 선들이 겹쳐있는 부분")하고 두 쌍 모두 손으로 뗐다.
|
|
362
|
+
* 겹침이 아니라 **맞닿음**이라 `group-overlap-unintended`(양 축 5px 초과 겹침)는 이 형상을 못 본다.
|
|
363
|
+
*
|
|
364
|
+
* 근거(오탐): 실무 18문서의 그룹쌍 65 중 이 상태는 **0건** — 사람은 테두리를 겹쳐 두지 않는다.
|
|
365
|
+
* 우리 산출물에서는 fixture 10종(그룹 2개 이상) 중 **7종**에서 났다(관측 11건 전부 간격 0).
|
|
366
|
+
*/
|
|
367
|
+
| {
|
|
368
|
+
kind: 'group-on-group-boundary';
|
|
369
|
+
groups: [string, string];
|
|
370
|
+
axis: 'x' | 'y';
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* **블랙박스 풀의 이름 텍스트**가 다른 요소의 외부 라벨과 겹쳤다(B-38) — 두 텍스트가 포개져 어느 쪽도
|
|
374
|
+
* 읽을 수 없는데, 종전에는 **아무 판정 채널도 이 텍스트를 보지 않았다**(DI 에 `BPMNLabel` 이 없고
|
|
375
|
+
* `auditTargetsOf` 는 컨테이너를 뺀다). G13 에서 사용자가 지목: 풀을 넓히자 이름이 중앙으로 따라
|
|
376
|
+
* 이동해 메시지 라벨을 덮었고 *"해당 문구는 선택 가능한 문구가 아니라서 에이전트가 판단이 될지 의문"*.
|
|
377
|
+
* 고치는 수단이 다르다 — 이름은 **옮길 수 없으므로**(위치 = 풀 중심 = 폭의 함수) 상대 라벨을 옮기거나
|
|
378
|
+
* 풀 기하를 바꾼다. `pool` = 그 참여자, `label` = 겹친 라벨의 소유자 id.
|
|
379
|
+
*
|
|
380
|
+
* 근거(오탐): 실무 13문서의 외부 라벨 302개 중 라벨끼리 겹친 쌍은 **0** 이다 — 사람은 텍스트를 겹쳐
|
|
381
|
+
* 두지 않는다. 우리 산출물에서도 이 겹침은 G10~G13 표본 전량 0건이다.
|
|
382
|
+
*/
|
|
383
|
+
/**
|
|
384
|
+
* **그룹의 테두리가 흐름노드를 가로지른다**(B-65) — 도형이 상자 안도 밖도 아니어서 그 노드가 어느
|
|
385
|
+
* 단계의 일인지 그림만 보고는 읽을 수 없다. 표본 55 에서 사용자가 지목: *"그룹에 반만 걸친 요소"*
|
|
386
|
+
* (`변경 완료 수신` 이 `배송` 상자에 **49%** 만 덮였다 · `주문 변경 접수` 는 `접수` 상자에 80%).
|
|
387
|
+
* 근인은 A-4 의 x∪y bbox 다 — 멤버가 흩어지면 상자가 남의 노드 위로 자란다.
|
|
388
|
+
*
|
|
389
|
+
* 🔴 **판별자는 「양」 이 아니라 「객체 종류」 다.** 같은 형상이 **주석**일 때는 사람도 한다
|
|
390
|
+
* (실무 26문서의 주석 5건 · B-46 이 그것을 재서 **취향 축**으로 판정하고 finding 을 안 뒀다).
|
|
391
|
+
* **흐름노드**로 좁히면 사람은 **0 건**이다(실무 그룹 36 중 0 · 저장본 8문서 15건). 그래서 이 판정은
|
|
392
|
+
* `NON_STAGE_TYPES` 를 뺀 대상에만 건다 — **B-46 의 판정을 뒤집는 것이 아니라 그 대상 집합 밖이다.**
|
|
393
|
+
*
|
|
394
|
+
* `depth` = 테두리선이 도형을 가른 자리에서 **작은 쪽 조각의 px**. 실측 분포가 **0.5~4px**(테두리가
|
|
395
|
+
* 도형 가장자리를 스친다)와 **16~49px**(진짜로 반이 잘린다)로 갈리고 그 사이가 비어 있어
|
|
396
|
+
* `GROUP_CUT_MIN_DEPTH` 를 그 골짜기에 둔다. ⚠ 실무 기저는 바닥값이 **없어도 0** 이므로, 얕은 쪽이
|
|
397
|
+
* 실제로 지목되는 회차가 나오면 근거를 들고 낮출 것.
|
|
398
|
+
*/
|
|
399
|
+
| {
|
|
400
|
+
kind: 'group-cuts-shape';
|
|
401
|
+
group: string;
|
|
402
|
+
shape: string;
|
|
403
|
+
side: 'top' | 'bottom' | 'left' | 'right';
|
|
404
|
+
depth: number;
|
|
405
|
+
} | {
|
|
406
|
+
kind: 'pool-name-over-label';
|
|
407
|
+
pool: string;
|
|
408
|
+
label: string;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* 🔴 **풀이 다른 풀과 겹친다 — 「가려짐」축**(B-91 · 표본 67). 한 풀이 다른 풀 위에 얹히면
|
|
412
|
+
* 아래 풀의 내용이 배경에 묻혀 **읽을 수 없다**. 근인은 배치의 **비대칭**이다 — 풀이 세로로
|
|
413
|
+
* 자랄 때는 `pushRootBelow` 가 아래를 밀지만 **가로로 자랄 때는 오른쪽을 안 민다**.
|
|
414
|
+
*
|
|
415
|
+
* ⚠ **관통 축으로는 못 잡는다** — `auditTargetsOf` 가 컨테이너를 전부 빼므로(`!s.container`)
|
|
416
|
+
* 풀은 애초에 관통·겹침 판정의 대상이 아니다. 그래서 표본 67 에서 POS 풀이 레전드 풀을
|
|
417
|
+
* **100% 덮었는데 문서 전체 판정이 0건**이었고, 사용자가 풀 3개를 손으로 드래그해 뺐다
|
|
418
|
+
* (증언: *"레전드 카드가 도형에 가려서 밖으로 뺀거야"*) — 🔁 **조용한 결함**(B-51·B-74 클래스).
|
|
419
|
+
*
|
|
420
|
+
* 🔴 **양을 재지 않는다 — 겹치는가만 본다.** 오탐 기저가 **0/97**(실무 0/26 · 저장본 0/74)이라
|
|
421
|
+
* 임계가 필요 없다. `contained` = 한쪽이 다른 쪽을 통째로 덮었다(가림이 가장 심한 형상).
|
|
422
|
+
*/
|
|
423
|
+
| {
|
|
424
|
+
kind: 'pool-overlap';
|
|
425
|
+
pools: [string, string];
|
|
426
|
+
contained: boolean;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* 🔴 **간선이 남의 서브프로세스를 관통한다**(B-91 ⓑ). `edge-crosses-shape` 가 이것을 못 보는
|
|
430
|
+
* 이유는 같다 — subProcess 가 `container` 라 대상에서 빠진다. 그런데 **사람 눈에는 도형**이고,
|
|
431
|
+
* 표본 67 에서 신규 간선 3건이 레전드 카드 안의 subProcess 를 가로질렀다.
|
|
432
|
+
*
|
|
433
|
+
* ⚠ **컨테이너 종류를 가르는 것이 판별자다**(🔁 B-65 「양이 안 가르면 대상을 갈라라」) —
|
|
434
|
+
* participant·lane·group 관통은 **정상 형상**이라 같이 잡으면 저장본에서만 **718건**이 터진다
|
|
435
|
+
* (실측: Participant 410 · Group 210 · Lane 98). subProcess 만 **0/97** 이다.
|
|
436
|
+
* ⚠ **collapsed 여부로는 못 가른다** — 표본 67 의 그 subProcess 들은 **expanded** 였다.
|
|
437
|
+
*/
|
|
438
|
+
| {
|
|
439
|
+
kind: 'edge-crosses-subprocess';
|
|
440
|
+
edge: string;
|
|
441
|
+
subProcess: string;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* 간선의 끝 웨이포인트가 **자기 끝점 도형에서 떨어져** 있다 — 선이 도형에 닿지 않는다(B-97).
|
|
445
|
+
*
|
|
446
|
+
* 🔴 **조용한 결함이다**(🔁 B-51 · B-74) — 기존 판정 19종은 전부 요소끼리의 **상호** 관계를 보고,
|
|
447
|
+
* 「간선이 자기 끝점에 붙어 있는가」라는 축이 아예 없었다. 그래서 컨테이너 리사이즈가 도형만
|
|
448
|
+
* 옮기고 간선을 두고 가도 **어느 표면도 침묵**했다(표본 71: 배치 응답 1건 · 문서 전체 3건이
|
|
449
|
+
* 나왔는데 그 안에 끊긴 선 26개가 없었다. 사용자는 *"선이 제대로 연결 자체가 안 된 상태"* 로
|
|
450
|
+
* 보고 그 레인 수정을 **포기**했다).
|
|
451
|
+
*
|
|
452
|
+
* ⚠ **임계 10px 은 N20 이 정했다** — 사람 실무 26종 기저가 `>4px` **0.55%** · `>10px` **0.21%**
|
|
453
|
+
* (남은 셋은 전부 association)인데, 표본 71 의 결함 42건은 **최소 11px** 이라 전량 잡힌다.
|
|
454
|
+
* 4px 로 내리면 정상 도킹의 반올림 오차를 줍고, 40px 로 올리면 그 결함의 대부분(12px 26건)을
|
|
455
|
+
* 놓친다. **컨테이너 끝점은 제외한다**(메시지플로우가 블랙박스 풀에 붙는 것은 정상이고 풀은
|
|
456
|
+
* 폭이 커 경계가 멀다).
|
|
457
|
+
*/
|
|
458
|
+
| {
|
|
459
|
+
kind: 'edge-endpoint-detached';
|
|
460
|
+
edge: string;
|
|
461
|
+
shape: string;
|
|
462
|
+
distance: number;
|
|
104
463
|
};
|
|
105
464
|
/** 발견을 전후 비교(배치가 새로 만든 것 가려내기)할 수 있게 하는 안정 키. */
|
|
106
465
|
export declare function geometryFindingKey(finding: GeometryFinding): string;
|
|
466
|
+
/**
|
|
467
|
+
* `processRef` 없는 참여자(= bpmn-js `isExpanded` 거짓)의 **이름 텍스트 사각형**. DI 에 없는 렌더 산물이라
|
|
468
|
+
* 여기서 산출한다 — 폭 근사는 주석 크기 산출과 같은 출처(`approximateTextWidth`)를 쓴다.
|
|
469
|
+
*
|
|
470
|
+
* 줄바꿈은 계산하지 않는다: 상자 폭이 풀 폭(1000px 이상)이라 실무·표본 전량에서 접히지 않았고, 명시 개행
|
|
471
|
+
* (`\n`)만 줄을 가른다. 접히는 이름이 관찰되면 그때 폭 기준 줄바꿈을 넣는다(조기 일반화 회피).
|
|
472
|
+
*/
|
|
473
|
+
export declare function blackBoxNameRect(pool: GeometryShape, name: string): GeometryLabel;
|
|
107
474
|
export interface AxisSegment {
|
|
108
475
|
axis: 'h' | 'v';
|
|
109
476
|
/** 고정 좌표(h 면 y, v 면 x). */
|
|
@@ -116,15 +483,32 @@ export interface AxisSegment {
|
|
|
116
483
|
/** 간선의 축 정렬 구간들(웨이포인트 순서). 사선 구간은 뺀다. */
|
|
117
484
|
export declare function axisSegmentsOf(edge: GeometryEdge): AxisSegment[];
|
|
118
485
|
/**
|
|
119
|
-
* 두 간선의
|
|
120
|
-
*
|
|
486
|
+
* 두 간선의 **읽을 수 없는** 공선 중첩 — 방향이 반대(`opposite`)이거나, 같은 방향인데 종류가 다른
|
|
487
|
+
* (`mixed`: 실선 × 점선) 겹침. 가장 긴 것의 (축, 길이, 종류). 없으면 `null`. 같은 종류·같은 방향
|
|
488
|
+
* (합류·팬아웃)은 세지 않는다 — 사용자가 그대로 두는 형상이다(표본 4·7).
|
|
489
|
+
*/
|
|
490
|
+
export declare function unreadableOverlapOf(a: GeometryEdge, b: GeometryEdge): {
|
|
491
|
+
axis: 'h' | 'v';
|
|
492
|
+
length: number;
|
|
493
|
+
kind: 'opposite' | 'mixed' | 'unrelated';
|
|
494
|
+
} | null;
|
|
495
|
+
/**
|
|
496
|
+
* 읽을 수 없는 공선 중첩 **3종**(반대 방향 · 종류 다름 · 무관) 판정인가.
|
|
497
|
+
* 🔴 소비자가 `kind` 목록을 손으로 늘리게 두면 축을 하나 더할 때마다 **조건이 좁은 소비자**가 남는다
|
|
498
|
+
* (🔁 「기존 축의 조건이 좁았다」 — B-19·B-27·B-65·B-71 이 그 클래스다). 늘리는 자리는 여기 하나다.
|
|
121
499
|
*/
|
|
500
|
+
export declare function isEdgeOverlapFinding(f: GeometryFinding): f is Extract<GeometryFinding, {
|
|
501
|
+
kind: 'edge-overlap-opposite' | 'edge-overlap-mixed' | 'edge-overlap-unrelated';
|
|
502
|
+
}>;
|
|
503
|
+
/** 두 간선의 **반대 방향** 공선 중첩(종류 무관). `unreadableOverlapOf` 의 부분집합 — 기존 호출자 호환. */
|
|
122
504
|
export declare function oppositeOverlapOf(a: GeometryEdge, b: GeometryEdge): {
|
|
123
505
|
axis: 'h' | 'v';
|
|
124
506
|
length: number;
|
|
125
507
|
} | null;
|
|
126
508
|
/** 한 간선(후보 경로)이 다른 간선들과 만드는 반대 방향 중첩 수. */
|
|
127
509
|
export declare function oppositeOverlapCount(edge: GeometryEdge, others: readonly GeometryEdge[]): number;
|
|
510
|
+
/** 한 간선(후보 경로)이 다른 간선들과 만드는 읽을 수 없는 중첩 수(반대 방향 + 종류 다름) — 보정의 목적 함수. */
|
|
511
|
+
export declare function unreadableOverlapCount(edge: GeometryEdge, others: readonly GeometryEdge[]): number;
|
|
128
512
|
/** bpmn-js `LabelUtil.FLOW_LABEL_INDENT` — 라벨 중심이 선에서 떨어지는 거리(가로 구간은 위, 세로 구간은 오른쪽). */
|
|
129
513
|
export declare const FLOW_LABEL_INDENT = 15;
|
|
130
514
|
/**
|
|
@@ -145,6 +529,14 @@ export declare function sharedSegmentUnderLabel(edge: GeometryEdge, others: read
|
|
|
145
529
|
other: string;
|
|
146
530
|
axis: 'h' | 'v';
|
|
147
531
|
} | null;
|
|
532
|
+
export declare function lineCrossesLabel(label: GeometryLabel, seg: AxisSegment): boolean;
|
|
533
|
+
/** 컨테이너 도형의 네 변을 축 정렬 구간으로 — 레인·풀 경계선. */
|
|
534
|
+
export declare function containerBoundarySegments(shape: GeometryShape): AxisSegment[];
|
|
535
|
+
/**
|
|
536
|
+
* 이 간선의 라벨을 가로지르는 선 — 자기 간선 구간 → 다른 간선 구간(id 순) → 컨테이너 경계선(id 순). 첫 것의 id.
|
|
537
|
+
* 없으면 `null`. 판정과 보정(routeRepair `planLabelLineClearance`)이 같은 술어를 쓴다.
|
|
538
|
+
*/
|
|
539
|
+
export declare function lineThroughLabel(edge: GeometryEdge, scene: GeometryScene): string | null;
|
|
148
540
|
/**
|
|
149
541
|
* 이 간선이 관통하는 도형들(자기 끝점 제외). 판정과 **우회 보정**(routeRepair)이 같은
|
|
150
542
|
* 술어를 써야 "고쳤다는데 판정은 그대로"가 나지 않는다.
|
|
@@ -157,10 +549,51 @@ export declare function crossedShapesOf(edge: GeometryEdge, targets: readonly Ge
|
|
|
157
549
|
* 같은 노드에서 나가는 팬아웃·같은 노드로 드는 합류는 꺾이는 자리가 겹쳐 보여도 교차가 아니다.
|
|
158
550
|
*/
|
|
159
551
|
export declare function edgeCrossCount(edge: GeometryEdge, others: readonly GeometryEdge[]): number;
|
|
552
|
+
/**
|
|
553
|
+
* 교차 **비용**(B-18 ⓑ) — 같은 종류(실선×실선)의 교차는 2, 종류가 다른(실선×점선) 교차는 1. 여덟 번째 표본의
|
|
554
|
+
* 사용자 우선순위: "어쩔 수 없을 땐 크로스될 수밖에 없지만 가급적 **다른 종류의 선**과 크로스되는 게 구분이
|
|
555
|
+
* 좋다". 후보 선택의 교차 축은 이 비용으로 재고, 계측(`edgeCrossCount`·`stats`)은 개수 그대로 둔다.
|
|
556
|
+
*/
|
|
557
|
+
export declare function crossingCost(edge: GeometryEdge, others: readonly GeometryEdge[]): number;
|
|
558
|
+
/** 장면 전체의 교차 비용 합(쌍마다 같은 종류 2 · 다른 종류 1). */
|
|
559
|
+
export declare function sceneCrossingCost(scene: GeometryScene): number;
|
|
160
560
|
/** 장면 전체의 교차 쌍(id 오름차순 정렬, 결정론적). 길이가 곧 교차 수다. */
|
|
161
561
|
export declare function edgeCrossingPairsOf(scene: GeometryScene): Array<[string, string]>;
|
|
162
|
-
/**
|
|
562
|
+
/**
|
|
563
|
+
* 교차 쌍을 **에이전트가 판단할 수 있는 재료로 분해**한다(B-43). 개수만으로는 "이 정도가 정상인가" 를
|
|
564
|
+
* 가릴 수 없고, 지금까지 세 회차에서 같은 마찰이 났다(표본 34·36 은 재료 없이도 결론이 맞았으나
|
|
565
|
+
* 표본 47 에서는 에이전트가 **판정을 보류**했다). 산출 비용은 0 이다 — 종류는 이미 `type` 에 있다.
|
|
566
|
+
*
|
|
567
|
+
* - `solidPairs` / `dashedPairs` / `mixedPairs` — 교차 쌍을 **선 스타일 조합**으로 가른다.
|
|
568
|
+
* `solidPairs`(실선×실선 = 시퀀스끼리)가 **배치를 다시 볼 신호**다 — 풀 횡단으로 설명되지 않는다.
|
|
569
|
+
* `mixedPairs`(실선×점선)는 풀을 건너는 메시지가 시퀀스를 지나는 정상 형상이 대부분이다.
|
|
570
|
+
* `dashedPairs`(점선×점선 = 메시지·데이터 연관끼리)는 **둘과 또 다르다** — 대개 장거리 데이터 연관이
|
|
571
|
+
* 여러 메시지를 지나는 형상이라 노드 배치가 아니라 저장소·연관의 열이 원인이다.
|
|
572
|
+
*
|
|
573
|
+
* 🔴 **축이 둘이었을 때 뜻이 어긋났다**(표본 48 실측) — `sameKind` 는 "같은 스타일끼리" 를 셌는데
|
|
574
|
+
* 주석·playbook 은 "실선끼리" 라고 불렀다. G18 의 `sameKind 2` 는 전부 `DA_chg × M_*`(점선×점선)였고
|
|
575
|
+
* 실선끼리는 **0** 이었는데, 에이전트가 이름을 믿고 "재볼 신호인 실선끼리 교차 2건" 으로 보고했다.
|
|
576
|
+
* 이름이 재료를 왜곡하면 판단이 그 위에 선다 ⇒ 축을 셋으로 갈라 이름과 뜻을 일치시킨다.
|
|
577
|
+
*
|
|
578
|
+
* - `crossPoolMessages` — 두 끝점 사이에 **다른 풀이 끼어 있는** 메시지플로우 수. 인접 풀끼리 주고받는
|
|
579
|
+
* 메시지는 아무것도 건너지 않지만 이것들은 지나가는 풀의 시퀀스와 **구조적으로** 만난다.
|
|
580
|
+
* playbook §6 의 "풀 횡단 메시지 1개당 교차 1" 감을 실제로 계산할 수 있게 하는 분모다(= `mixedPairs` 의).
|
|
581
|
+
*/
|
|
582
|
+
export declare function edgeCrossingStatsOf(scene: GeometryScene): {
|
|
583
|
+
pairs: Array<[string, string]>;
|
|
584
|
+
solidPairs: number;
|
|
585
|
+
dashedPairs: number;
|
|
586
|
+
mixedPairs: number;
|
|
587
|
+
crossPoolMessages: number;
|
|
588
|
+
};
|
|
163
589
|
export declare const auditTargetsOf: (scene: GeometryScene) => GeometryShape[];
|
|
590
|
+
/** 도형의 외부 이름 라벨을 가로지르는 선 — 간선 구간(id 순) → 컨테이너 경계선(id 순). 첫 것의 id, 없으면 `null`. */
|
|
591
|
+
export declare function lineThroughShapeLabel(shape: GeometryShape, scene: GeometryScene): string | null;
|
|
592
|
+
/** 장면의 외부 라벨 전부(도형 이름 라벨 + 간선 라벨)와 그 소유자 — 판정과 주석 배치(6단계 장애물)가 같은 목록을 쓴다. */
|
|
593
|
+
export declare function labelRectsOf(scene: GeometryScene): Array<{
|
|
594
|
+
owner: string;
|
|
595
|
+
rect: GeometryLabel;
|
|
596
|
+
}>;
|
|
164
597
|
/**
|
|
165
598
|
* 기하 판정 (순수). 결과는 **결정론적 순서**로 정렬해 반환한다 — 전후 diff·골든 비교·회귀
|
|
166
599
|
* 고정이 전부 순서에 의존한다.
|
|
@@ -8,7 +8,7 @@ export type { DocumentIndex, ElementCategory } from './documentIndex';
|
|
|
8
8
|
export { buildRegistryIndex } from './documentIndex';
|
|
9
9
|
export { validateOps } from './validate';
|
|
10
10
|
export { lowerOps, resolverServicesOf, type ResolverServices } from './lower';
|
|
11
|
-
export { planCrossPoolRoute, planEdgeRepair, planLabelPlacement, planMiddleSegmentShifts, planOppositeOverlapRepair, planSegmentDetours, repairIntroducedCrossings, repairIntroducedOppositeOverlaps, repairIntroducedSharedSegmentLabels, rerouteIntroducedCrossPoolEdges, } from './routeRepair';
|
|
11
|
+
export { forwardThreePointCandidates, planCrossPoolRoute, planEdgeRepair, planLabelLineClearance, planLabelPlacement, planMiddleSegmentShifts, planOppositeOverlapRepair, planSegmentDetours, planBackEdgeBoundaryClearance, repairIntroducedBoundaryHugging, repairIntroducedCrossings, repairIntroducedEdgeCrossings, repairIntroducedFakeMerges, repairIntroducedOppositeOverlaps, repairIntroducedSharedSegmentLabels, followMovedEdgeLabels, redockIntroducedDetachedEndpoints, repairIntroducedLabelLines, repairIntroducedShapeLabelLines, planShapeLabelClearance, rerouteIntroducedCrossPoolEdges, } from './routeRepair';
|
|
12
12
|
export interface ApplyBpmnOpsResult {
|
|
13
13
|
ok: boolean;
|
|
14
14
|
issues: ResolveIssue[];
|
|
@@ -30,6 +30,32 @@ export interface ApplyBpmnOpsResult {
|
|
|
30
30
|
edgeCrossings: {
|
|
31
31
|
before: number;
|
|
32
32
|
after: number;
|
|
33
|
+
/**
|
|
34
|
+
* 하강 뒤 남은 진성 교차 쌍(간선 id, 오름차순) — 개수만으로는 "이 정도가 정상인가"를 에이전트가
|
|
35
|
+
* 판단할 수 없다(G12 마찰: 교차 5 를 받고 어느 선끼리인지 몰라 배치 재검토를 못 했다).
|
|
36
|
+
* 쌍을 보면 한 메시지가 여러 시퀀스를 건너는 것인지(풀 횡단 = 정상) 배치가 엉킨 것인지 갈린다.
|
|
37
|
+
*/
|
|
38
|
+
pairs: Array<[string, string]>;
|
|
39
|
+
/**
|
|
40
|
+
* **실선×실선**(시퀀스끼리) 교차 쌍 수(B-43) — 풀 횡단으로 설명되지 않으므로 **배치를 다시 볼 신호**다.
|
|
41
|
+
*/
|
|
42
|
+
solidPairs: number;
|
|
43
|
+
/**
|
|
44
|
+
* **점선×점선**(메시지·데이터 연관끼리) 교차 쌍 수(B-43). 실선끼리와도 실선×점선과도 뜻이 다르다 —
|
|
45
|
+
* 대개 장거리 데이터 연관이 여러 메시지를 지나는 형상이라 원인이 노드 배치가 아니라 저장소·연관의 열이다.
|
|
46
|
+
* 🔴 종전 `sameKind` 는 이것과 `solidPairs` 를 **한 칸에 묶어** 이름이 뜻을 왜곡했다(표본 48).
|
|
47
|
+
*/
|
|
48
|
+
dashedPairs: number;
|
|
49
|
+
/**
|
|
50
|
+
* **실선×점선** 교차 쌍 수(B-43) — 풀을 건너는 메시지가 시퀀스를 지나는 정상 형상이 대부분이다.
|
|
51
|
+
* 분모는 `crossPoolMessages` 이고, 그 몇 배인지를 본다.
|
|
52
|
+
*/
|
|
53
|
+
mixedPairs: number;
|
|
54
|
+
/**
|
|
55
|
+
* 두 끝점 사이에 **다른 풀이 끼어 있는** 메시지플로우 수(B-43) — 그런 메시지는 지나가는 풀의
|
|
56
|
+
* 시퀀스와 구조적으로 만난다. playbook §6 의 "풀 횡단 메시지 1개당 교차 1" 감의 **분모**다.
|
|
57
|
+
*/
|
|
58
|
+
crossPoolMessages: number;
|
|
33
59
|
};
|
|
34
60
|
};
|
|
35
61
|
}
|
|
@@ -102,6 +102,18 @@ export type ResolveIssue =
|
|
|
102
102
|
opIndex: number;
|
|
103
103
|
id: string;
|
|
104
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* `node.add`/`node.update` 의 type 이 **만들 수 있는 집합 밖** — 읽을 수 있다고 만들 수 있는 것이
|
|
107
|
+
* 아니다(B-87 ⓐ). describe 는 `subProcess`·`boundaryEvent` 를 노드로 내지만 그 둘의 배치 하강은
|
|
108
|
+
* 미실증이다(subProcess = 내부 좌표계 · boundaryEvent = `attachedToRef` 좌표 종속). 스키마 enum 이
|
|
109
|
+
* 1차 방어이고 이 issue 가 2차 방어다 — 호스트가 스키마를 집행하지 않기 때문(payload-invalid 주석 참조).
|
|
110
|
+
*/
|
|
111
|
+
| {
|
|
112
|
+
kind: 'node-type-unsupported';
|
|
113
|
+
opIndex: number;
|
|
114
|
+
id: string;
|
|
115
|
+
type: string;
|
|
116
|
+
}
|
|
105
117
|
/** lanes 재선언이 기존 레인을 누락 — 레인 축소는 미실증 축(B-0)이라 거부 (세션 ②-b 판단) */
|
|
106
118
|
| {
|
|
107
119
|
kind: 'lane-shrink-unsupported';
|