이 노트에 대하여

lifetract가 정지된 건강 데이터 자료실에서 벗어나, Home Assistant를 통해 매일 들어오는 생체·시간 데이터 인터페이스로 재정의되는 순간을 기록한다. Samsung Health → Health Connect → HA Companion App → lifetract로 이어지는 새 경로가 통과하면서, geworfen과 에이전트가 같은 단어로 몸과 시간을 물을 수 있는 기반이 생긴다.

히스토리

  • [2026-05-19 Tue 09:06] @junghan — 링크 검토를 하자.
  • [2026-05-18 Mon 18:20] @glg — 공개 botlog 연결 보강. 건강 자동화 데이터 로그 메타를 추가하고, phase 3.5 multi-sensor oracle 검증 llmlog까지 관련노트에 연결.
  • [2026-05-18 Mon 10:00] @gptglg(oracle) — 1주일치 sleep 시도 → HA recorder 에 2건만. phase 3 의 진짜 경계 발견: HA 는 적립 인프라라 인프라가 뜬 시점부터의 데이터만 존재. 과거는 Samsung CSV 가 유일한 길. 향후 매일 1줄씩 누적 (오늘 2일 → 다음 주 9일 → 한 달 뒤 30일).
  • [2026-05-18 Mon 09:35] @gptglg(oracle) — phase 3 binary 로 “어제 잘 잤나?” 첫 라이브 응답. ha state sleep_duration 으로 어젯밤 415분 (≈6h55m, 종료 04:48 KST) 답. "lifetract read 2026-05-17 에는 상세 세션이 없어서 HA 실시간 센서 기준" — lazy 모델의 정신을 코드 없이 에이전트가 자연스럽게 잡은 자리.
  • [2026-05-18 Mon 09:10] @claude — lifetract repo baton 한 번 회수. NEXT.md §1 을 on-query lazy ingest 모델로 재정의 (cron-only batch 폐기, 디바이스별 db sync 회피), today off-by-one fix, ha.go 인터페이스 phase 3 (read-only client + 24 entity declarative 등록) 통과. ha.junghanacs.com 에서 heart 111bpm, sleep 415분 실시간 수신. 작업기록 [denote:20260518T090443].
  • [2026-05-18 Mon 06:39] @glg — 공개 botlog 형식에 맞춰 #+description 과 abstract를 추가하고, 관련메타/관련노트 그래프를 lifetract·geworfen·homeagent·Open Home Foundation 축으로 보강.
  • [2026-05-17 Sun 21:25] @junghan — 검토하자
  • [2026-05-17 Sun 21:17] 생성 — 검토 단계 llmlog([Health Connect → HA → lifetract 자동화 경로 검토]) 이후 실제로 인프라를 띄우고 PoC end-to-end 통과한 시점의 botlog. 같은 날 안에 “고민”이 “연결”로 넘어간 기록.

관련메타

관련노트

멈춰있던 자리

오랫동안 lifetract 안에는 내 신체 데이터(Samsung Health)와 시간 데이터(aTimeLogger) — 즉 내 시간축의 두 본축 — 의 누적과 해석 코드가 잘 모여 있었다. 해석 방법까지 만들어 두었다. 그런데 활용도가 낮았다.

이유는 단순했다. 데이터를 옮기는 것 자체가 불편했다.

  • Samsung Health → Settings → Export 수동 클릭, 몇 달 간격
  • 그 사이 사용자는 어제 잘 잤는지 조차 자기 코드베이스 안에서 답할 수 없었다
  • 해석은 끝났는데 흐름 이 없는 상태

좋은 코드와 좋은 해석이 있어도, 데이터가 한 번에 한 덩어리씩 손으로 옮겨지면 시간축은 끊긴다. lifetract 는 정지된 자료실에 가까웠다.

분기점 — Health Connect codelab에서 시작

오늘 오후 Health Connect codelab 검토에서 출발해 후보를 단계적으로 좁혔다. 자세한 검토 흐름은 [llmlog] 에 보존되어 있고, 결론만 옮긴다.

후보결과
Kotlin 자체 앱 (codelab 학습)학습 비용 — 제외
Flutter 미니 앱익숙하지만 굳이 — 제외
Tasker GUI통제 약함 — 제외
Health Sync 유료 third-party통제 권한 없음 — 제외
Home Assistant Companion App + 자체 HA 인스턴스채택

결정적 발견 두 가지가 있었다.

  1. Samsung Health → Health Connect 가 권한 화면에서 수면 심박/HRV/걸음 체중 /혈압/SpO2/VO2 Max까지 전 메트릭 위임 가능
  2. Health Connect → HA Companion App 이 2024년부터 정식 데이터 소비자로 노출됨 — 추가 앱 개발 없이 바로 다리(bridge)가 된다

자체 앱을 만들지 않아도 되는 길이 이미 있었다.

연결 — 오늘 직접 띄우고 데이터가 흐르기 시작했다

Oracle ARM 클라우드 인스턴스의 Docker 위에 HA를 올렸다. caddy reverse proxy는 이미 다른 서비스(remark42, umami, geworfen)에 쓰고 있어서 동일한 단일 컨테이너 패턴을 한 번 더 복제했다.

  • 도메인: ha.junghanacs.com (health 가 아니라 ha — 헬스만이 아니라 IoT/자동화 허브 전체 확장 의도)
  • 도커 이미지: ghcr.io/home-assistant/home-assistant:stable (멀티아치 aarch64)
  • 네트워크: proxy external bridge에 가입. ports publish 없음 (caddy 통해서만 접근)
  • 사전 박은 configuration.yamluse_x_forwarded_for: true + trusted_proxies: [172.18.0.0/16, ::1, 127.0.0.1] + recorder.purge_keep_days: 30 + ip_ban_enabled: true

Let’s Encrypt 인증서 자동 발급, 첫 부팅, onboarding, admin TOTP 2FA, Galaxy 디바이스(SM-S942N) 등록, Companion App 안에서 Health Connect 센서 토글 — 한 시간 안에 모두 통과.

PoC 검증의 첫 라인이 다음 값을 가리켰다.

sensor.sm_s942n_s26_glgman_sleep_duration       = 427 min   # 어젯밤 7시간 7분
sensor.sm_s942n_s26_glgman_heart_rate           = 96 bpm
sensor.sm_s942n_s26_glgman_resting_heart_rate   = 72 bpm
sensor.sm_s942n_s26_glgman_daily_steps          = 11,044
sensor.sm_s942n_s26_glgman_weight               = 75.0 kg
...

내 어젯밤 수면 시간이 처음으로 내 시스템 안의 텍스트 로 떠올랐다.

시간축이 다시 흐른다는 것

이것은 단지 데이터 파이프라인 한 줄이 추가된 사건이 아니다.

내 시간축의 두 본축인 Samsung HealthaTimeLogger 중, 하나가 옮겨오지 않아도 자기 흐름을 유지하게 되었다. 두 번째 본축인 aTimeLogger 와 합쳐지면 lifetract 는 다시 자기 자리를 찾는다 — 자료실이 아니라 *데이터 인터페이스*로.

이 인터페이스가 향할 두 표면(surface)이 이미 보인다.

  • geworfen 홈페이지 — 시간축을 사람에게 보여주는 자리. 외부로 향한다
  • 에이전트 호출 — “어제 힣 잘잤나?” 한 줄에 그 즉시 답이 나오는 자리. 안으로 향한다

두 표면이 같은 인터페이스를 공유한다. 즉 lifetract 가 잘 만들어지면 사람과 에이전트가 같은 단어로 내 몸과 시간을 묻는다. 이 일치가 만들어진다는 것이 오늘의 본질이다.

강력한 신호 — IoT 본업과의 만남

내 본업은 IoT 개발이다. 오랫동안 연결 에 대해 고민해 왔고, 그 고민이 자기 도메인 바깥(데이터·자료·일·시간) 으로 천천히 확장되어 왔다. 오늘의 사건은 그 두 줄기가 만난 지점이다.

  • IoT의 본질: 디바이스 → 신뢰할 수 있는 데이터 흐름 → 의미 있는 자동화
  • 내 개인의 본질: 자기 시간 → 신뢰할 수 있는 자기 데이터 → 자기 해석

같은 모양이다. Home Assistant 의 모회사인 Open Home Foundation 이 추구하는 방식 — 지역(local) 우선, 사용자 통제, 표준 인터페이스 — 이 자기 시간축에도 그대로 적용된다는 것을 오늘 직접 확인했다.

내가 운영 중인 homeagent-config 는 이 만남의 연결고리 역할을 한다. Open Home Foundation 방향의 자동화·에이전트 흐름에 나의 시간축 과 나의 에이전트 군단 을 묶어 두기 위한 작업이다. 오늘 PoC 통과로 그 연결의 한 마디가 들어맞았다.

이것은 단순히 되네 가 아니라, *방향이 맞다는 강한 신호*다.

다음 자리 — lifetract repo로 baton

인프라 layer(HA 컨테이너 + caddy + LE + Companion App 등록 + Health Connect 토글)는 nixos-config 에 닫았다. 오늘 커밋 시퀀스(9214a6e, 7567b7c, 53a8d2e) 가 그 인프라 마침표다.

이제 다음 자리는 lifetract 다.

  • AGENTS.md 신설 — 현재 부재. README/SKILL 은 있지만 에이전트 담당자 문서가 빠짐. 코드도 3월 이후 손 안 댔다 → 실제 동작과 문서 정렬부터
  • HA REST polling import — GET /api/states/sensor.sm_s942n_s26_glgman_* 일1회 cron. 토큰은 password-store 에 보관 (이미 발급 완료)
  • aTimeLogger 파서와의 통합 표면
  • geworfen / 에이전트의 “어제 힣 잘잤나?” 호출의 backend 면

인터페이스가 부실하면 오늘의 연결도 다시 죽는다. lifetract 는 자기 정체성을 자료실 에서 인터페이스 로 옮겨야 한다. 그게 baton 의 본문이다.

다음 자리 갱신 — 2026-05-18 phase 3 통과

baton 의 첫 묶음이 통과해서, 위 4개 항목의 상태가 다음과 같이 바뀌었다.

baton 항목5/17 상태5/18 상태
AGENTS.md 신설부재완료 (d193a49) — repo 정체성 + 운영 룰 + NEXT.md 동시 신설
HA REST polling import0%재정의 — cron-only batch 가 디바이스별 db sync 부담을 만들어 on-query lazy ingest 모델로 전환. Phase 3 (read-only client + 24 entity) 통과.
aTimeLogger 통합 표면이미 됨변동 없음 — 기존 atl_category / atl_interval 그대로
geworfen / 에이전트 표면0%인터페이스 자리 닦임ha state heart_rate 같은 라이브 호출 가능. 본 구현은 phase 4-5 후 활성화

5/17 baton 의 “cron 한 번” 대신 “호출이 곧 ingest” 로 결정한 자리가 본질적이다. lifetract.db 가 디바이스마다 분산되어 자라도, HA 가 진짜 SSOT 라 sync 부담이 사라진다. 인터페이스가 단순해진다.

5/18 시점의 다음 자리 (phase 4 이후):

  • DB 마이그레이션: 기존 테이블에 source TEXT 컬럼 + UNIQUE (date, source) ([samsung_csv | ha_rest])
  • cmdToday / cmdRead 에 lazy hook — DB miss 시 HA REST 호출 → DB upsert → 답
  • lifetract ingest --ha 명시 커맨드 — cron / 수동 trigger 용
  • Oracle systemd timer 등록 (nixos-config 측) — oracle 의 db 신선도 baseline
  • lifetract status 에 HA 표시 (ha.last_pull, ha.token_valid)
  • AGENTS.md §2 “두 입력 스트림” → “세 입력 스트림” 으로 갱신
  • SKILL.md (본 repo + agent-config 양쪽) 에 ha 커맨드 추가

phase 3 의 의미: lifetract 가 비로소 실시간 시간축 위에 설 자리가 만들어졌다. “어제 힣 잘잤나?” 의 backend 가 코드로 잡혀가는 중이다.

첫 라이브 응답과 첫 경계 — phase 3 의 의미 검증

phase 3 통과 약 30분-1시간 사이, oracle GPT힣 이 phase 3 binary 로 두 번 질문을 받았다. 두 번이 phase 3 의 양면 을 그대로 보여준다.

1. “어제 잘 잤나?” — 성공

어제 수면 시간: 415분 ≈ 6시간 55분. 종료 2026-05-18 04:48 KST. 출처: Samsung Health → Home Assistant live sensor. lifetract read 2026-05-17 에는 상세 세션이 안 들어와서, 이번 값은 DB 가 아니라 HA 실시간 센서 기준으로 봤어.

본 botlog 의 비전 — “사람과 에이전트가 같은 단어로 내 몸과 시간을 묻는다” — 이 코드 한 줄 추가 없이도 자연스럽게 작동한 첫 케이스. 결정적 디테일은 “DB 가 아니라 HA 실시간 센서 기준” 한 줄이다. phase 4 의 lazy hook 이 코드로 들어가기 전, 에이전트가 자연어 수준에서 이미 lazy 모델을 잡아 답한다. phase 4 는 이 자연스러움을 기계적으로 보장하는 자리지, 발명하는 자리가 아니다.

2. “1주일치는?” — 경계 발견

HA history 에도 현재 이 센서 기록이 2건만 있음. 최근 2일은 대략 7시간 전후, 2일 평균 약 7시간 1분.

phase 3 의 진짜 경계가 여기서 드러난다. sensor.sm_s942n_s26_glgman_sleep_duration 의 history 가 2건만 있는 이유는 HA 의 한계가 아니라 *HA 가 *적립 인프라** 라는 본질이다. recorder 는 state 변화 시점에만 row 저장하고, HA 인프라 자체가 2026-05-17 에 띄워졌으므로 그 이전 sleep session 의 state 는 HA 에 존재한 적이 없다. recorder 30일 보관은 “있는 데이터 보존” 이지 “없는 데이터 채워줌” 이 아니다.

따라서 본 도구의 시간 지평이 두 결로 나뉜다:

  • Samsung 의 과거 — 2017-03 ~ 2026-03. CSV export 로 받아 lifetract.db 에 영속. 9년 누적이지만 수동 export 사이클 이 끊겼던 자리
  • HA 의 미래 — 2026-05-17 ~. 매일 1 row 씩 적립. 다음 주에 9일치, 한 달 뒤 30일치
  • 두 결이 만나는 자리가 phase 4 의 lazy upsert. 과거 + 미래 가 같은 DB 안에서 한 시간축이 되어야 비로소 “지난 1년 수면 패턴” 같은 질문이 답을 얻는다

phase 3.5 (ha history CLI) 를 곧 추가한다. 지금 즉시 효용은 작지만 (어차피 HA 에 2건), 내일부터의 누적이 매일 늘어나는 자리이고 phase 4 lazy backfill 의 기반 부품이다.

정리

  • 첫 답은 한 줄로 나왔다 (성공의 정신)
  • 첫 경계는 정직하게 보였다 (적립 인프라의 본질)
  • 두 결이 phase 4 에서 만난다 (Samsung CSV + HA recorder)

데이터를 옮기는 일이 멈춘 자리에서, 인터페이스가 사람의 질문을 만나러 왔다. 그게 오늘의 본질이다.

한 줄 요약

데이터를 옮기는 일을 멈추고, 인터페이스가 데이터를 만나러 오게 한 날. 내 시간축이 자기 시스템 안에서 다시 흐른다.