@hatiolab/figure-model 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -1
- package/dist/asset-types.d.ts +14 -4
- package/dist/asset-types.d.ts.map +1 -1
- package/dist/asset.d.ts +11 -0
- package/dist/asset.d.ts.map +1 -1
- package/dist/asset.js +24 -10
- package/dist/asset.js.map +1 -1
- package/dist/authoring-actions.d.ts.map +1 -1
- package/dist/authoring-actions.js +8 -4
- package/dist/authoring-actions.js.map +1 -1
- package/dist/gate.d.ts +14 -2
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js +45 -25
- package/dist/gate.js.map +1 -1
- package/dist/graph-types.d.ts +33 -6
- package/dist/graph-types.d.ts.map +1 -1
- package/dist/graph.d.ts +7 -0
- package/dist/graph.d.ts.map +1 -1
- package/dist/graph.js +175 -52
- package/dist/graph.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/joint-list.d.ts.map +1 -1
- package/dist/joint-list.js +5 -3
- package/dist/joint-list.js.map +1 -1
- package/dist/kernel-version.d.ts +1 -1
- package/dist/kernel-version.js +1 -1
- package/docs/completeness-review-2026-10-04.md +256 -0
- package/docs/status.md +12 -1
- package/package.json +1 -1
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# figure-model 완결성·확장성 점검
|
|
2
|
+
|
|
3
|
+
점검일: 2026-10-04. 대상: 작업 트리가 깨끗한 `4610edc`(패키지 0.3.2).
|
|
4
|
+
코드와 공개 계약을 검토하고 `npm test` 및 별도 경계 사례를 실행했다.
|
|
5
|
+
런타임 코드를 변경하거나 발행하지 않았다. 설치된 제품 및 npm 배포 상태는 이번 점검 범위가 아니다.
|
|
6
|
+
|
|
7
|
+
## 해결 현황 (2026-10-04, 미발행)
|
|
8
|
+
|
|
9
|
+
F1~F4를 고쳤다. 항목마다 기존 코드에서 실패하는 회귀 시험을 먼저 넣었고, 고친 뒤 `npm test`(타입 검사와
|
|
10
|
+
725개 시험)와 build가 통과한다. 재현 스크립트는 이제 네 항목 모두 거절 또는 정상 결과를 출력한다.
|
|
11
|
+
`npm run test:coverage`의 기준(줄 100%, 분기 95%)은 점검 시점 HEAD에서도 못 미쳤다(줄 96.87%, 분기 89.24%).
|
|
12
|
+
고친 뒤 줄 96.91%, 분기 89.50%이며 새 코드에 덮이지 않은 줄은 없다.
|
|
13
|
+
|
|
14
|
+
| 항목 | 커밋 | 선택한 계약 | 시험 |
|
|
15
|
+
| -------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
|
|
16
|
+
| F1 결과 소유권 | `122b3c0` | 인스턴스 evaluator 결과의 values 레코드와 geometry 목록은 호출자 소유이고, 그 안의 값과 body는 동결된다. 쓰기는 TypeError로 거절된다. 내부 슬롯은 동결하지 않은 비공개 객체로 두고, 결과에는 값이 바뀔 때 만든 동결 사본을 넣는다. 형상은 제자리에서 동결한다. 바뀌지 않은 형상·body는 같은 객체로 이어진다. 전체 평가(`plan.evaluate`)는 아무것도 보관하지 않으므로 결과 전체가 호출자 소유이고 동결하지 않는다. pose step의 `bodies`·`poses`는 호출자 사본이고, `read`·`changed`는 같은 evaluator의 다음 호출 전까지만 답하며 그 뒤에는 `STEP_EXPIRED`로 거절된다. | `src/result-ownership.test.ts` |
|
|
17
|
+
| F2 공개 검증 | `c86d74b` | `compileFigureAsset`이 관절 목록, 레코드 schema, 레코드와 노드 일치를 검사한다. serialize·parse는 같은 검사를 거친다. 저작 명령은 관절 노드를 레코드에서 다시 쓰므로 입구와 명령 중간의 자세 읽기에는 관절 검사 없는 내부 컴파일(`compileFigureAssetUnjointed`, 패키지 밖으로 내보내지 않음)을 쓰고, 명령 결과는 공개 compile로 검사한다. | `src/asset-entrances.test.ts` |
|
|
18
|
+
| F3 깊은 그래프 | `4f32334` | 컴파일 순회가 자체 스택을 쓴다. 선언 순서 깊이 우선이라는 순서, 타입·단위·상태 거절, 순환 경로 표기(들어선 곳부터)가 이전과 같다. 같은 재귀가 있던 gate의 design 의존성 계산도 컴파일 순서 한 번 훑기로 바꿨다. `compileFigureGraph`는 자체 크기 한도가 없고, byte·노드 한도는 document·asset 입구의 계약이다. | `src/graph-depth.test.ts` |
|
|
19
|
+
| F4 검사 옵션 | `9a332e7` | 설정 오류는 Figure를 컴파일하기 전에 `INSPECT_OPTION`(경로 `options.<키>`)으로 거절한다. `sweepSteps`는 2 이상 정수, `maxCornerInputs`는 0~12 정수다. 실행할 상태 수를 첫 평가 전에 세어 8,192를 넘으면 `INSPECT_BUDGET`으로 거절한다. 코너 열거는 32비트 시프트를 쓰지 않는다. 한도는 `FIGURE_INSPECT_LIMITS`로 내보낸다. | `src/inspect-options.test.ts` |
|
|
20
|
+
|
|
21
|
+
비용(Node, 호출당, 점검 HEAD 대비):
|
|
22
|
+
|
|
23
|
+
- F1: 무변경 평가, pose step, 전체 평가는 그대로다(로봇 6축 0.55 / 9.7 / 61 µs). evaluate 경로에서 바뀐 값의
|
|
24
|
+
사본 비용이 붙는다. 컨베이어 상태 1개 7.4→13.7 µs, 로봇 관절 1개 4.8→9.6 µs, 관절 7개 12→20 µs,
|
|
25
|
+
설계값 1개 30→52 µs(롤러 컨베이어). fixture의 상태 입력 대부분은 pose step을 타므로 프레임마다 도는 경로는
|
|
26
|
+
늘지 않는다. 슬롯을 제자리에서 동결하는 방식도 쟀으나 숫자 배열이 박싱되어 pose step 9.8→15 µs,
|
|
27
|
+
관절 7개 evaluate 12→35 µs로 더 느려 채택하지 않았다.
|
|
28
|
+
- F2: 관절이 있는 자산의 compile이 parse와 같은 비용이 된다(hinged-door 2.3→5.7 ms, parse 6.4 ms 그대로).
|
|
29
|
+
저작 명령 하나에 약 3 ms가 붙는다.
|
|
30
|
+
|
|
31
|
+
장면 프레임(things-scene `FigureRig.update`, Node CPU, 렌더러 GPU 제외, 600프레임 평균, 발행판 0.3.2 → 수정본):
|
|
32
|
+
|
|
33
|
+
| 장면 | 0.3.2 | 수정본 | 증가 |
|
|
34
|
+
| ----------------------------------------------------------- | ----------------- | -------------------------- | --------- |
|
|
35
|
+
| 컨베이어 60대, clip 회전(pose step) | 0.34 ms | 0.37 ms | +5~10% |
|
|
36
|
+
| 로봇 20대, 관절 전부 움직임(pose step) | 0.29 ms | 0.31 ms | +5% |
|
|
37
|
+
| 지게차 20대, 상태 전부 움직임(pose step) | 0.38~0.43 ms | 0.39~0.42 ms | 차이 없음 |
|
|
38
|
+
| 문+램프 60대, 램프 flag를 넘나드는 제어(매 프레임 evaluate) | 0.22 ms | 0.34~0.37 ms | +55% |
|
|
39
|
+
| 컨베이어 60대, 크기 끌기(매 프레임 evaluate·형상 변경) | 4.05 ms (p95 6.0) | 5.6~~6.0 ms (p95 7.8~~9.1) | +40~45% |
|
|
40
|
+
| 로봇 20대, 관절 이동 + 10프레임마다 크기 변경 | 0.46 ms (p95 1.7) | 0.53 ms (p95 2.2) | +15% |
|
|
41
|
+
|
|
42
|
+
evaluate 경로의 증가는 사본 비용이다. 크기 변경 한 번에 롤러 컨베이어가 복사하는 객체는 약 100개(자세 25, 행 항목 22,
|
|
43
|
+
경로 배열 22)이고 객체당 약 100 ns다. 회전 공유, spread 복사, 심볼 캐시를 시험했으나 줄지 않았고, 사본 중복 제거용
|
|
44
|
+
Map은 없애면 오히려 느려졌다(10.4→15.9 µs). 더 줄이려면 body·행 항목을 제자리에서 동결하고 자세만 복사하는 설계
|
|
45
|
+
변경이 필요하며, 행의 pose step 경로가 동결 자세를 읽게 되는지 따로 검토해야 한다. 발행 전 판단 대상이다.
|
|
46
|
+
|
|
47
|
+
소비자 검증(things-scene 10.1.71 작업 트리, `test/tsconfig.figure-model-src.json`으로 형제 소스를 연결해 실행.
|
|
48
|
+
연결 여부는 소스에만 있는 `FIGURE_INSPECT_LIMITS`로 확인):
|
|
49
|
+
|
|
50
|
+
- 단위·figure 시험 전체 2,713개: 발행판과 수정본 모두 통과. figure 시험 107개 안에 결과 조회(pose step과 evaluate
|
|
51
|
+
혼합 시 모든 mesh 위치), 부착물(관절이 움직이는 부품의 place, 그리퍼 끝의 workpiece), 선택(병합·묶음 mesh의 pick이
|
|
52
|
+
부품·사본으로 돌아옴), sizing(크기 변경 후 복귀, 선언 범위 밖 크기, 위에서 본 그림)이 있다.
|
|
53
|
+
- 타입: 빌드된 `dist/*.d.ts`에 대해 things-scene을 검사했다. 인스턴스 결과를 readonly로 표현하기 전에는 오류 0개,
|
|
54
|
+
표현한 뒤에는 오류 2개다. 둘 다 쓰기가 아니라 선언 타입 문제다. `figure-rig.ts`의 `movePoses` 인자 타입이
|
|
55
|
+
`places`의 자세를 가변 배열로 선언했고, `dress`가 `result.bindings`를 가변 `FigureAssetEvaluation`으로 돌려준다.
|
|
56
|
+
things-scene이 이 판으로 올릴 때 두 선언에 `readonly`를 붙여야 한다. 이번 작업에서는 소비자를 고치지 않았다.
|
|
57
|
+
- things-factory·operato-application 소스에는 인스턴스 evaluator 사용처가 없다.
|
|
58
|
+
|
|
59
|
+
API 호환성 영향:
|
|
60
|
+
|
|
61
|
+
- 인스턴스 evaluator 결과의 중첩 객체에 쓰던 호출자는 TypeError를 받는다. things-scene의 `FigureRig`는 결과를 쓰지
|
|
62
|
+
않고 pose step의 `read`·`changed`도 같은 단계 안에서만 부른다(capabilities 래퍼 포함).
|
|
63
|
+
- 관절 레코드와 노드가 어긋난 자산은 이제 compile·serialize에서도 거절된다. parse가 이미 거절하던 자산이다.
|
|
64
|
+
render-batches 시험 하나가 그런 자산을 손으로 만들고 있어 관절이 읽지 않는 치수를 늘리도록 고쳤다.
|
|
65
|
+
- 검사 옵션의 잘못된 값은 이전의 계산 오류나 빈 sweep 대신 `INSPECT_OPTION`으로 거절된다. 기본값 결과는 같다.
|
|
66
|
+
- 추가된 공개 이름: `FIGURE_INSPECT_LIMITS`, 오류 코드 `STEP_EXPIRED`·`INSPECT_OPTION`·`INSPECT_BUDGET`,
|
|
67
|
+
타입 `FigureFrozen`·`FigureInstanceEvaluation`·`FigureCapabilityInstanceEvaluation`.
|
|
68
|
+
- 인스턴스 evaluator의 `evaluate`와 evaluate로 끝난 `advance`의 결과 타입이 위 instance 타입으로 바뀐다(내용이 deep
|
|
69
|
+
readonly). 전체 평가 타입은 그대로다. 소유 계약은 README 「Evaluation results: who owns what」에 적었다.
|
|
70
|
+
|
|
71
|
+
남은 제한:
|
|
72
|
+
|
|
73
|
+
- evaluate 경로의 사본 비용(위 수치). 값 레코드를 읽을 때만 사본을 만드는 방식은 레코드 복사·직렬화 의미를
|
|
74
|
+
바꾸므로 보류했다.
|
|
75
|
+
- `compileFigureGraph`를 직접 부르는 호출자는 그래프 크기를 스스로 책임진다. 전체 평가 예산(geometry 합계,
|
|
76
|
+
slot 수)은 정하지 않았다.
|
|
77
|
+
- 검사 예산 8,192 상태는 상태 수 한도이고 시간·메모리 상한은 아니다.
|
|
78
|
+
- 아래 「확장성」, 「검사·성능 숫자의 해석」 항목은 이번 범위가 아니다.
|
|
79
|
+
|
|
80
|
+
### 발행 판정 (2026-10-04)
|
|
81
|
+
|
|
82
|
+
- 정확성 수정은 유지하고, 성능 비용을 밝힌 채 발행을 준비한다. 발행 설명은 「정확성·검증 경계 개선, 일반 평가
|
|
83
|
+
비용 증가」다. 자세 경로 성능 개선이나 렌더링 성능 유지로 설명하지 않는다.
|
|
84
|
+
- 성능 검증은 CPU rig 측정까지만 했다. 브라우저 전체 프레임 목표를 충족하는지는 확인하지 않았다.
|
|
85
|
+
- readonly 타입은 유지한다. things-scene `4b21c72c`가 두 선언(`movePoses`·`dress`, 그리고 자세를 행렬로 읽는
|
|
86
|
+
`pose`·`matrixOf`)을 읽기 전용으로 고쳤다. figure-model 0.3.2와 새 소스 모두에 대해 타입 검사 오류가 0개이고,
|
|
87
|
+
단위·figure 시험 2,787개가 둘 다에서 통과한다. things-scene의 figure-model 범위는 발행 뒤에 올린다.
|
|
88
|
+
- 복사 구조 재설계(대규모 resize 최적화)는 별도 과제다. 결과 소유권 결함을 다시 열지 않고, 브라우저 전체 프레임의
|
|
89
|
+
중앙값·p95를 기준으로 진행한다.
|
|
90
|
+
|
|
91
|
+
## 종합 판단
|
|
92
|
+
|
|
93
|
+
이 패키지는 **이름 있는 부품의 치수·자세·반복·연결을 선언하고, 같은 정의를 저작·검사·씬에서 소비하는
|
|
94
|
+
장비 조립체 커널**로는 충분한 구조를 갖췄다. 임의 CAD, 물리 시뮬레이터, 모든 JavaScript 형상을 대체하는
|
|
95
|
+
범용 모델로 완결됐다고 말할 근거는 없다. 현재 기능 범위와 공개 API의 경계 조건도 구분해야 한다.
|
|
96
|
+
|
|
97
|
+
| 차원 | 판단 | 근거와 제한 |
|
|
98
|
+
| --------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
99
|
+
| 계산 의미 | 양호, 결과 소유권 보완 필요 | 단위·좌표계·단일 writer·순환 검사, 상태 전이 의존성, 순수 평가. 중첩 결과 수정이 다음 증분 평가에 유입됨 |
|
|
100
|
+
| 저작과 저장 | 양호, 검증 입구 통합 필요 | UI/AI 명령 공유, revision·원자 적용·undo. compile/serialize와 parse가 관절을 다르게 검증함 |
|
|
101
|
+
| 검사 완결성 | 명시적 제한 있음 | proven/sampled/defaults 구별은 좋음. 표본은 범위 보장이 아니며 검사 옵션 검증이 부족함 |
|
|
102
|
+
| 자원·안전 경계 | 부분적 | JSON 1 MiB/깊이 64, document 8,192노드, 반복 전개 한도. 긴 의존 사슬에서 일반 스택 오류 발생 |
|
|
103
|
+
| 성능 | 증분·자세 실행 구조 양호 | 인스턴스 상태 분리, 입력 영향 범위, 형상 공유 친화적 결과. 큰 출력 대비 소수 변경의 버퍼 할당은 개선 후보 |
|
|
104
|
+
| 확장성·유지보수 | 통제된 확장에 적합 | 버전 연산·형상 description·공유 명령. 연산 추가 시 여러 정책표를 함께 수정해야 하며 자동 기본값과 any가 실수를 가릴 수 있음 |
|
|
105
|
+
|
|
106
|
+
`npm test`: 타입 검사와 **696개 시험 통과**, 실패·skip·todo 없음(약 23.8초, 이번 환경).
|
|
107
|
+
시험 통과는 아래 경계 사례까지 검증됐다는 뜻이 아니다. 이번에 코드 커버리지 수치나 브라우저 성능을 새로 측정하지 않았다.
|
|
108
|
+
|
|
109
|
+
## 우선 고칠 사항: 재현된 문제
|
|
110
|
+
|
|
111
|
+
### F1. 평가 결과의 중첩 객체가 evaluator 내부와 공유됨 — 높은 우선순위
|
|
112
|
+
|
|
113
|
+
> 해결됨(2026-10-04). 위 「해결 현황」 참고. 아래는 점검 당시의 기록이다.
|
|
114
|
+
|
|
115
|
+
근거: `src/graph.ts`의 `hold`(1080행), `step` 반환, `src/graph-types.ts`의 가변 출력 타입.
|
|
116
|
+
`hold`는 values record와 geometry 배열만 복사한다. 그 안의 shape·pose·배열은 내부 slot과 공유된다.
|
|
117
|
+
주석은 호출자의 수정이 다음 평가에 도달하지 않는다고 설명하지만 실제 보장은 최상위 컨테이너까지다.
|
|
118
|
+
|
|
119
|
+
재현: 폭 5cm의 shape를 평가하고 반환된 `shape.dimensions['size.x']`를 999로 수정했다.
|
|
120
|
+
같은 입력의 다음 증분 평가 결과는 999, 새 전체 평가 결과는 정상값 50이었다.
|
|
121
|
+
기존 `incremental.test.ts`는 values의 새 속성 추가와 geometry push를 검사하며 중첩 수정을 검사하지 않는다.
|
|
122
|
+
|
|
123
|
+
개선: 공유되는 결과 객체를 실제 불변으로 만들어 동일성·캐시 이점을 보존하거나, 공개 결과와 내부 버퍼를
|
|
124
|
+
깊게 분리한다. 문서만 readonly로 바꾸는 것은 JavaScript 호출자의 변경을 막지 않는다.
|
|
125
|
+
무조건 매 프레임 deep clone하기 전에 형상·자세의 공유 단위를 정하고 비용을 측정해야 한다.
|
|
126
|
+
회귀 검증은 shape, pose, collection/member 중첩 수정과 인스턴스 간 격리를 포함한다.
|
|
127
|
+
|
|
128
|
+
### F2. 관절 검증이 공개 입구마다 다름 — 높은 우선순위
|
|
129
|
+
|
|
130
|
+
> 해결됨(2026-10-04). 위 「해결 현황」 참고. 아래는 점검 당시의 기록이다.
|
|
131
|
+
|
|
132
|
+
근거: `src/asset.ts`의 `compileFigureAsset`, `serializeFigureAsset`(208행), `parseFigureAsset`(212행).
|
|
133
|
+
관절의 schema·정본/그래프 일치 검사는 parse에서만 `checkFigureJoints`로 실행한다.
|
|
134
|
+
|
|
135
|
+
재현: hinged-door의 fixed joint에 금지된 `axis: 'Z'`를 추가했다.
|
|
136
|
+
compile과 serialize는 성공했지만, 직후 그 JSON을 parse하면 `JOINT_SCHEMA`로 실패했다.
|
|
137
|
+
따라서 공개 serializer가 공개 parser로 읽을 수 없는 데이터를 만들어 낼 수 있다.
|
|
138
|
+
|
|
139
|
+
개선: 공개 저장·컴파일 입구에서 동일한 자산 검증을 사용한다.
|
|
140
|
+
관절 재작성 과정이 미완성 자산을 컴파일해야 한다면, 내부 전용 경로와 공개 검증을 분리해 재귀 호출을 피한다.
|
|
141
|
+
합격 기준은 공개 serialize→parse의 일관성과 관절 레코드/그래프 drift의 동일한 거절이다.
|
|
142
|
+
|
|
143
|
+
### F3. 허용 크기 안의 깊은 그래프에서 스택 초과 — 높은 우선순위
|
|
144
|
+
|
|
145
|
+
> 해결됨(2026-10-04). 위 「해결 현황」 참고. 아래는 점검 당시의 기록이다.
|
|
146
|
+
|
|
147
|
+
근거: `src/graph.ts`의 재귀 `visit`(864행), `src/document.ts`의 노드 한도,
|
|
148
|
+
`src/shape-ops.test.ts`의 큰 그래프 시험.
|
|
149
|
+
|
|
150
|
+
재현: 선언 순서를 의존 순서와 반대로 놓은 add 사슬을 document로 컴파일했다.
|
|
151
|
+
2,000·5,000·8,000노드 모두 이번 Node 환경에서 `RangeError: Maximum call stack size exceeded`로 실패했다.
|
|
152
|
+
각 JSON은 약 151·382·613KB로 1 MiB보다 작고 노드 수도 8,192 이하이다.
|
|
153
|
+
현재 큰 그래프 시험은 모두 입력 `a`를 직접 읽는 넓은 그래프라 이 경계를 잡지 못한다.
|
|
154
|
+
|
|
155
|
+
개선: 반복형 DFS 또는 Kahn 위상 정렬로 바꾸고 cycle 경로 진단을 유지한다.
|
|
156
|
+
지원 깊이에 제한을 둔다면 명시적 `FigureContractError`로 거절한다.
|
|
157
|
+
공개 `compileFigureGraph`는 document의 byte/node 경계를 거치지 않으므로, 저수준 API의 신뢰·예산 계약도 명시한다.
|
|
158
|
+
반복마다 10,000개의 전개 한도가 있어도 전체 geometry 합계·slot·검사 실행 수가 자동으로 제한되지는 않는다.
|
|
159
|
+
전체 평가 예산을 추가할지 별도 결정하고, 실제 메모리 상한은 측정한다.
|
|
160
|
+
|
|
161
|
+
### F4. 검사 옵션을 검증하지 않아 잘못된 숫자가 계산 오류로 나타남 — 중간 우선순위
|
|
162
|
+
|
|
163
|
+
> 해결됨(2026-10-04). 위 「해결 현황」 참고. 아래는 점검 당시의 기록이다.
|
|
164
|
+
|
|
165
|
+
근거: `src/gate.ts`의 `inspectFigureAsset`, 544~580행.
|
|
166
|
+
hinged-door에서 `sweepSteps: 1`은 0/0 때문에 `NON_FINITE`, 2.5는 입력 범위를 넘는 표본 때문에
|
|
167
|
+
`INPUT_RANGE`, 0은 sweep 없이 sampled 결과로 성공했다.
|
|
168
|
+
이는 Figure 자체가 아니라 검사 설정의 문제인데 진단에서 구별되지 않는다.
|
|
169
|
+
|
|
170
|
+
개선: sweepSteps를 2 이상 유한 정수로 검증하고 최대 표본 수를 제한한다.
|
|
171
|
+
maxCornerInputs도 유한 정수·지원 범위로 검증한다.
|
|
172
|
+
`1 << inputs.length`는 32비트 시프트이므로 옵션으로 31개 이상 전수 코너를 허용하면 산술도 부정확해진다.
|
|
173
|
+
전수 표본 수를 사전에 계산해 예산을 확인하며, sampled/defaults 의미를 그대로 보존한다.
|
|
174
|
+
|
|
175
|
+
재현 명령:
|
|
176
|
+
|
|
177
|
+
```sh
|
|
178
|
+
node scripts/audit-completeness-2026-10-04.mjs
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
이 스크립트는 관찰을 출력하는 점검 도구다. 결함이 남아 있어야 통과하는 회귀 시험이 아니다.
|
|
182
|
+
계약을 검증하는 회귀 시험은 「해결 현황」 표의 시험 파일에 있다.
|
|
183
|
+
|
|
184
|
+
## 확장성: 좋은 기반과 제약
|
|
185
|
+
|
|
186
|
+
### 현재 잘 갖춘 기반
|
|
187
|
+
|
|
188
|
+
- 단위와 frame을 타입으로 검사하고 상태 의존성을 전이적으로 전파한다. 관절 이름을 추측해 실행하지 않는다.
|
|
189
|
+
- 공유 컴파일 결과와 인스턴스별 evaluator 상태가 분리되어 있다. 증분·자세 경로는 기존 연산의 계산을 재사용하고 미지원 경로를 전체 평가로 돌린다.
|
|
190
|
+
- `shape-ops.ts`의 shape description이 측정·편집·feature를 연결한다. 새 형상을 추가할 때 소비자가 인자 위치를 제각각 해석할 필요가 줄었다.
|
|
191
|
+
- proposal의 command union 완전성 검사가 UI와 AI의 언어 차이를 줄인다. recipe는 데이터로 명령을 재사용한다.
|
|
192
|
+
- renderer 자체를 포함하지 않고 render plan을 제공한다. 등급과 렌더 묶음의 규칙을 공유할 수 있다.
|
|
193
|
+
- JSON duplicate key·비유한 값·getter·cycle 등 경계 방어가 있고, 검사 coverage가 표본과 증명을 구별한다.
|
|
194
|
+
|
|
195
|
+
### 기능상의 의도적 제약
|
|
196
|
+
|
|
197
|
+
| 영역 | 현재 범위·제약 | 확장할 때 필요한 것 |
|
|
198
|
+
| ----------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
|
199
|
+
| 형상 | extrude/revolve/loft. loft는 단면→점 피라미드이며 임의 다단면 loft가 아님 | sweep·mesh import·CSG 등이 필요하면 형상·bounds/support·feature·편집·삼각형 계산·renderer 계약까지 함께 설계 |
|
|
200
|
+
| 연결 | 강체 frame과 DAG/tree 기반 관절 | 폐쇄 기구·연립 제약은 명시 관계 블록과 해 선택·불능 진단. 부모 둘로 우회하지 않기 |
|
|
201
|
+
| 로봇 | 정방향 자세, 관절 목록과 mimic | IK·충돌·속도/토크·동역학은 현재 커널 보장이 아님. 외부 solver와 입력/출력 계약부터 정의 |
|
|
202
|
+
| mimic | 여러 leader의 선형 합은 지원. follower를 다시 leader로 쓰는 연결은 저작 검증에서 거절 | 다단 mimic이 필요하면 단위·순환·범위·관절 목록 파생 규칙까지 검토 |
|
|
203
|
+
| 반복 | design에 의한 유한 topology, state에 의한 내부 운동 | state에 따른 생성/삭제는 현재 count 정책 밖. ordinal key가 물리적 객체 정체성을 보장하는지도 별도 결정 |
|
|
204
|
+
| 저작 | 만들어진 recipe는 보통 부품으로 삽입되고 recipe와의 연결은 사라짐 | 재사용 하위 조립체의 원본 수정 전파가 필요하면 template/instance/override 버전 계약 필요 |
|
|
205
|
+
| capability | Capacity/Holdable/Transferable/FlowNode의 닫힌 목록 | 새 행동은 커널 선언과 scene 구현을 함께 추가. 이름만 추가하면 기능 지원이 아님 |
|
|
206
|
+
| 배치 최적화 | 반복·정적·동일 carrier 묶음, 재질/투명성/visibility 등 조건 | 장면 간 배칭·LOD·GPU 표현은 별도 소비자 설계와 실측 필요 |
|
|
207
|
+
|
|
208
|
+
이 제약들이 곧 결함은 아니다. 대표 장비에는 단순성과 결정성이 장점이다.
|
|
209
|
+
다만 README의 “코드로 만들 수 있는 형상을 데이터로 만들기”는 목표이며 현재의 무제한 표현력 보장이 아니다.
|
|
210
|
+
|
|
211
|
+
### 연산 확장 시 개선할 구조
|
|
212
|
+
|
|
213
|
+
`src/graph.ts` 675~707행은 새 연산에 state=`follows`, pure=true를 자동으로 준다.
|
|
214
|
+
주석의 “정책 없는 연산은 거절”과 달리 catalog에 넣기만 하면 기본 정책이 생긴다.
|
|
215
|
+
오늘의 순수 연산들에 대한 오답은 확인하지 않았지만, 향후 시간·외부 상태·topology 연산을 추가할 때
|
|
216
|
+
누락된 정책이 안전하게 거절되지 않는 구조다.
|
|
217
|
+
|
|
218
|
+
개선 방향은 연산 정의에 unit/frame signature, state policy, purity, pose form, extrema basis를 명시하고,
|
|
219
|
+
불명확한 항목은 컴파일 거절 또는 검사 sampled로 처리하는 것이다.
|
|
220
|
+
전체 목록을 고정하는 시험은 유지하되 정책 자체의 의미 검증을 대신하지 않도록 한다.
|
|
221
|
+
`Dynamic = any`는 현재 13개 파일에 있다. 먼저 연산 dispatch와 shape의 discriminated union부터 강화한다.
|
|
222
|
+
한 번에 모듈을 모두 나누기보다 graph 검증·실행·pose 분석·연산 catalog의 책임 경계를 점진적으로 분리한다.
|
|
223
|
+
|
|
224
|
+
## 검사·성능 숫자의 해석에서 보완할 것
|
|
225
|
+
|
|
226
|
+
1. `linear.scalable`은 모든 입력에서의 수학적 증명이 아니다. 현재 `release-metrics.ts`는 authored size와
|
|
227
|
+
일곱 resize 표본의 AABB 중심·extent 및 삼각형 수를 비교한다. bounds가 같아도 정점·feature가 같다는
|
|
228
|
+
결론은 나오지 않는다. `probe`가 기록되는 것은 좋다. 범위·상태·검증 방법을 더 명확히 하고, 실제
|
|
229
|
+
배칭의 허용 근거로 사용할 때에는 별도의 구조적 증명이나 정확한 geometry 동등성 조건을 요구한다.
|
|
230
|
+
2. `atLargest`는 size 축의 max 조합에서 잰 비용이지, 모든 design/state 조합의 최대 비용 증명이 아니다.
|
|
231
|
+
공개 pitch와 visibility·state-dependent geometry가 비용을 바꿀 수 있다. 측정점과 worst-case coverage를
|
|
232
|
+
구분하고 단조성 증명 또는 보수적 예산 계산을 추가한다. 현재 등급도 기본 입력의 등급이다.
|
|
233
|
+
3. `words.ts` 예산은 특정 장치에서 잰 draw/motion 값과 미측정 triangle 목표가 섞인다.
|
|
234
|
+
등급을 일반 장치의 fps 보장으로 사용하지 말고, 장치·renderer·kernel·측정 시나리오를 가진 비용 profile로
|
|
235
|
+
버전화하는 방향이 좋다. 최근 커널/rig 개선 뒤에도 기존 대당 계수가 유효한지는 재측정 대상이다.
|
|
236
|
+
4. poseStep은 변경이 없어도 전체 bodyCount 크기의 Int32/Float64 버퍼를 할당한 뒤 slice한다.
|
|
237
|
+
소수 변경에서도 쓰는 양보다 할당량이 커질 수 있다. 변경 없음의 빈 결과, 출력 크기 추정, 명시 수명의
|
|
238
|
+
내부 버퍼를 검토하되 이전 결과 보존을 먼저 정하고 할당·GC·전체 프레임 개선을 측정한다.
|
|
239
|
+
5. pose 결과의 `read`/`changed`는 내부 fast 슬롯·mark를 조회하는 closure다.
|
|
240
|
+
이전 step을 보관한 뒤 다음 advance 후 조회할 때의 수명 계약을 문서화해야 한다.
|
|
241
|
+
일반 snapshot과 frame 범위 조회 API를 혼동하지 않도록 한다.
|
|
242
|
+
|
|
243
|
+
위 항목은 재현된 F1~F4와 구분한 설계·측정 개선 후보이다. 새 성능 수치나 실제 장면 결함으로 주장하지 않는다.
|
|
244
|
+
|
|
245
|
+
## 권장 순서와 완료 조건
|
|
246
|
+
|
|
247
|
+
1. F1 결과 소유권과 F2 공개 검증 일관성을 결정·수정하고 중첩 mutation 및 serialize/parse 회귀 시험을 추가한다.
|
|
248
|
+
2. F3 반복형 그래프 컴파일과 F4 검사 옵션/실행 예산을 보완한다. 깊은·넓은·순환 그래프와 설정 경계를 확인한다.
|
|
249
|
+
3. 지원 기능·의도적 제한·증명/표본의 구별을 정본 문서에 모으고, 재현 script와 현행 상태 링크를 유지한다.
|
|
250
|
+
4. 새 연산의 정책을 필수화하고 catalog/type를 단계적으로 정리한다. 기존 자산의 의미와 fallback을 보존한다.
|
|
251
|
+
5. 비용 profile과 pose 할당을 실제 장면에서 검토한다. 정확성이 유지되고 전체 프레임이 개선될 때 채택한다.
|
|
252
|
+
6. IK·폐쇄 기구·새 형상·하위 template 등은 실제 요구 사례 순서로 별도 설계한다. 기능 수를 늘리는 것 자체를
|
|
253
|
+
완결성 지표로 삼지 않는다.
|
|
254
|
+
|
|
255
|
+
이번 완료 범위는 저장소 점검·문서화·재현 근거 마련이다. 런타임 결함 수정, 소비자 전체 검증,
|
|
256
|
+
배포·발행은 후속 작업이며 수행하지 않았다.
|
package/docs/status.md
CHANGED
|
@@ -3,7 +3,18 @@
|
|
|
3
3
|
> 이 파일은 짧은 안내다. 결정은 `operato-application/adr/`(ADR-0087 · ADR-0093 · ADR-0096), 현재 상태는
|
|
4
4
|
> `operato-application/packages/operato-figure/docs/CURRENT_STATUS.md` 가 정본이다.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
최근 저장소 점검: 2026-10-04, figure-model 0.3.2 (`4610edc`).
|
|
7
|
+
|
|
8
|
+
- 완결성·확장성 및 공개 경계 검토: [점검 결과](completeness-review-2026-10-04.md).
|
|
9
|
+
- 점검 때 `npm test`: 타입 검사와 696개 시험 통과.
|
|
10
|
+
- 재현된 F1~F4는 같은 날 고쳤다(`122b3c0` · `c86d74b` · `4f32334` · `9a332e7`, 미발행). 고친 뒤 `npm test`는
|
|
11
|
+
타입 검사와 725개 시험 통과, build 성공. 선택한 계약과 남은 제한은 점검 결과 문서의 「해결 현황」에 있다.
|
|
12
|
+
- 발행 판정: 「정확성·검증 경계 개선, 일반 평가 비용 증가」. 성능은 CPU rig까지만 쟀다(매 프레임 evaluate
|
|
13
|
+
+40~55%). 대규모 resize 최적화는 별도 과제다.
|
|
14
|
+
- 남은 개선 후보(연산 정책 필수화, 비용 profile, pose 버퍼 할당, IK·새 형상·하위 template)는 별도 과제다.
|
|
15
|
+
- 아래 제품 설치 정보는 **2026-09-27 당시 기록**이다. 현재 설치 버전 확인 결과로 읽지 않는다.
|
|
16
|
+
|
|
17
|
+
제품 연결 기록 기준일: 2026-09-27.
|
|
7
18
|
|
|
8
19
|
- 모델러·AI·저장·렌더러는 한 형식(`figure-asset-1`)을 쓴다. 옛 형식은 2026-09-26 코드와 명세에서 없앴다.
|
|
9
20
|
- 제품 서버 localhost:3300 은 이 형식으로 돈다(figure-model 0.1.92 · things-scene 10.1.60 · tf 10.1.75).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hatiolab/figure-model",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "The figure format (figure-asset-1): a kernel that evaluates a figure from its declared relations, the authoring commands a modeller and an AI share, the release gate and the score.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"figure",
|