move_detect/docs/fall-lifecycle.archify.json
유창욱 34506e150d docs: 설계 도해 3종 (구성 · 낙상 시퀀스 · 낙상 상태기계)
archify 소스 JSON 만 커밋한다. HTML 은 생성물이라 사용설명서와 같은 이유로
gitignore — 소스가 바뀐 뒤에도 낡은 사본이 최신처럼 보이기 때문.

시퀀스를 그리면서 드러난 것: 경광등은 확정 즉시(3초)지만 메일·웹훅은
크론 주기를 기다려 최대 63초다. 문서가 둘을 "통보"로 묶어 쓰던 표현이
실제로는 20배 차이나는 두 경로였다.

상태기계는 확정 창 3초와 추락 연결 창 3초가 겹쳐 있는 구조를 한 장에
담았다 — 4차 감사에서 잡은 CRITICAL(추락 승격 미발화)의 원인이고,
시간축을 그렸다면 코드를 읽기 전에 보였을 충돌이다.

검증: deliver 9/9 · 오류 0 · 경고 0, visual-check 1440x900 / 1600x1000 /
1920x1080 / 2048x1320 양 테마 containment·가독성 통과.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBjuR7DW6PNNMows4KnbYU
2026-09-18 22:59:17 +09:00

217 lines
4.8 KiB
JSON

{
"schema_version": 1,
"diagram_type": "lifecycle",
"meta": {
"title": "낙상 판정 상태기계 — 지속을 요구하는 이유",
"output": "move-detect-fall-lifecycle.html",
"quality_profile": "showcase",
"views": [
{
"id": "main-path",
"label": "확정까지",
"focus": [
"standing",
"falling",
"fallen",
"nomotion"
],
"note": "한 프레임으로는 아무것도 확정하지 않는다. 1초는 위험 자세, 3초라야 넘어짐."
},
{
"id": "recovery",
"label": "회복 경로",
"focus": [
"falling",
"nearfall",
"fallen",
"recovered"
],
"note": "회복도 지속을 요구한다. 확정 전에 일어서면 니어미스로만 남는다."
},
{
"id": "lost-track",
"label": "사라진 사람",
"focus": [
"fallen",
"ghost"
],
"note": "위험 상태에서 트랙이 사라지면 10초 기다린 뒤 별도 사건으로 올린다."
}
],
"viewBox": [
1085,
620
]
},
"lanes": [
{
"id": "main",
"label": "자세 상태"
},
{
"id": "recovery",
"label": "회복"
},
{
"id": "terminal",
"label": "종료"
}
],
"states": [
{
"id": "standing",
"type": "start",
"label": "정상",
"sublabel": "기립 · 보행",
"lane": "main",
"col": 0,
"step": "01"
},
{
"id": "falling",
"type": "active",
"label": "위험 자세",
"sublabel": "쓰러진 자세 1초",
"lane": "main",
"col": 1,
"step": "02",
"tag": "알람 없음"
},
{
"id": "fallen",
"type": "failure",
"label": "넘어짐 확정",
"sublabel": "3초 지속",
"lane": "main",
"col": 2,
"step": "03",
"tag": "경광등 + 통보"
},
{
"id": "nomotion",
"type": "failure",
"label": "미동 없음",
"sublabel": "정지 10초",
"lane": "main",
"col": 3,
"step": "04",
"tag": "최상위 위급"
},
{
"id": "ghost",
"type": "failure",
"label": "위험 상태 소실",
"sublabel": "트랙이 사라짐",
"lane": "terminal",
"col": 2,
"tag": "10초 대기",
"yOffset": -16
},
{
"id": "nearfall",
"type": "neutral",
"label": "니어미스",
"sublabel": "확정 전 회복",
"lane": "recovery",
"col": 0,
"tag": "기록만"
},
{
"id": "recovered",
"type": "success",
"label": "정상 복귀",
"sublabel": "정상 자세 1초",
"lane": "recovery",
"col": 1
}
],
"transitions": [
{
"id": "to-falling",
"from": "standing",
"to": "falling",
"label": "쓰러진 자세 1초",
"labelDy": -46,
"route": "straight"
},
{
"id": "to-fallen",
"from": "falling",
"to": "fallen",
"label": "3초 지속",
"variant": "emphasis",
"labelDy": -46,
"route": "straight"
},
{
"id": "to-nomotion",
"from": "fallen",
"to": "nomotion",
"label": "정지 10초",
"variant": "emphasis",
"labelDy": -46,
"route": "straight"
},
{
"id": "to-ghost",
"from": "nomotion",
"to": "ghost",
"label": "재출현 없음",
"variant": "security",
"route": "right-channel",
"channelX": 720,
"labelSegment": 0
},
{
"id": "near-miss",
"from": "falling",
"to": "nearfall",
"label": "정상 1초",
"route": "drop"
},
{
"id": "fallen-recover",
"from": "fallen",
"to": "recovered",
"label": "정상 1초",
"route": "drop"
},
{
"id": "back-from-nearmiss",
"from": "nearfall",
"to": "standing",
"label": "복귀",
"variant": "dashed",
"route": "bottom-channel"
}
],
"cards": [
{
"dot": "emerald",
"title": "지속을 요구하는 이유",
"items": [
"한 프레임으로는 확정하지 않는다",
"1초는 위험 자세 — 알람 없음",
"앉는 동작과 가르는 조건이 이것이다"
]
},
{
"dot": "rose",
"title": "회복도 지속을 요구한다",
"items": [
"정상 자세 1초라야 회복",
"가려지면 카운트다운이 멈춘다",
"확정 전 회복은 니어미스로만"
]
},
{
"dot": "amber",
"title": "같은 3초가 두 번",
"items": [
"확정 창 3초 · 추락 연결 창 3초",
"겹쳐서 추락 승격이 미발화했다",
"시간을 그렸다면 보였을 충돌"
]
}
]
}