Skip to content

fix(logging): metadata 직렬화 실패로 backend_logs 행이 유실되던 문제 - #6

Open
jinsoo96 wants to merge 9 commits into
mainfrom
fix/backend-logger-nonserializable-metadata
Open

fix(logging): metadata 직렬화 실패로 backend_logs 행이 유실되던 문제#6
jinsoo96 wants to merge 9 commits into
mainfrom
fix/backend-logger-nonserializable-metadata

Conversation

@jinsoo96

@jinsoo96 jinsoo96 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

문제

BackendLogger._logjson.dumps(metadata) 를 default 없이 호출한다.
metadata 에 DB row 를 그대로 싣는 호출부(예: xgen-workflow deploy.py
metadata=deploy_meta)에서 created_at/updated_at datetime 을 만나면
TypeError 로 터지고, except 가 이를 삼켜 backend_logs 행이 통째로 유실된다.
서비스는 죽지 않지만 관리자 화면에서 해당 이력이 비어 보인다.

운영 로그에서 실제 발생:

backend-logger - ERROR - Error logging backend data: Object of type datetime is not JSON serializable
INFO: POST /api/agentflow/deploy/status/wf_... HTTP/1.1" 200 OK

변경

  • default=str — datetime/Decimal/UUID 등 직렬화 불가 값을 문자열로 보존
    (행 유실 대신 값 보존을 우선)
  • ensure_ascii=False — 한글 metadata 가 유니코드 이스케이프로 저장되지 않게

json.dumpsinsert_record 이전 단계라 DB 트랜잭션에는 영향이 없고,
성공 경로 동작도 동일하다.

테스트

tests/test_backend_logger_metadata.py 3건 추가:

  • datetime/Decimal/UUID metadata 로도 행이 저장되고 에러 로그가 없을 것
  • 한글 metadata 가 읽을 수 있는 형태로 저장될 것
  • metadata 가 없으면 빈 객체 문자열 유지

패치 전에는 앞의 2건이 실패하는 것을 확인했다 (유효한 회귀 테스트).

jinsoo96 and others added 8 commits July 23, 2026 19:08
- harness/skill_forge/ 13모듈: 메모리→스킬 자가승격 루프 —
  signals(후보신호)→curator(안티학습·안전필터·patch우선)→synthesis(guide/
  config/tool 3형)→gate(SelfForge promote 대수+결정적 재현벤치, LLM-judge 0)
  →ledger(semver·provenance·lineage·wilson)→recall(PD 2단)+drafter(3층복구·
  앙상블·예시유출가드)+host(SpineStore 어댑터)+bench(재현벤치·자동캡처).
  의존성 0, 원본 레포 engine/skill-forge-engineering(테스트 50 green).
- tools/skill_registry.py: register_ledger_source — 빌트인/코드등록/
  entry_points에 이은 4번째 회상 소스(원장 스킬을 get_skill_body/
  list_skill_names에 폴백 병합, staged 노출은 소스 정책)

검증: 원장 스킬 회상 노출 통합테스트 + 라이브 스택 E2E(실 PG skill_def
영속, qwen-turbo/qwen3-8b/qwen3.6-27b/claude-sonnet-4-6 동일 산출)
D1 검증 active 스킬의 미검증 강등 차단 / D2 drafted=[] 폴백 금지 의미론 /
D3 view() 순수 본문(frontmatter 오염 제거, 콘솔용 view_annotated 분리) /
D4 repetition __dict__ 백도어 제거 / D5 앙상블 샘플별 관점 변주.
원본 engine/skill-forge-engineering 54 green, 라이브 스택 스모크 통과.
completer 예외(HTTP 본문 포함)·파싱 실패·수리 실패를 WARNING 으로 노출.
원본 engine/skill-forge-engineering 56 green.
승격에 holdout 이득>0 요구(require_holdout_gain). dev 만 오른 스킬은
staged 로 강등 — 일반화 증거 없는 자동 verified 를 구조적으로 차단.
엔진(jinsoo96/jermes `e1a0bff`)의 변경을 흡수본에 반영한다. "0건 초안"이
모델 빈배열 / 예시유출 가드 / 필드 파손 중 무엇인지 한 줄로 구분해 남긴다.

드리프트 테스트(test_absorption_drift)가 원본-흡수본 불일치를 실제로 잡아
`absorb.py --force` 로 재흡수한 결과다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
엔진(jinsoo96/jermes `20c468f`)의 portable 모듈과 스펙 위반 수정을 흡수한다.
플랫폼이 `xgen_sdk.harness.skill_forge.portable` 로 표준 SKILL.md 를 내보내고
들여올 수 있다. 검증 증거는 스펙이 허용한 metadata 로 싣는다.

같이 온 수정: description 60자 절단 제거(스펙 1024·발견 품질의 핵심), YAML 이
깨질 수 있던 날값 기록, 스펙에 없는 최상위 필드를 metadata 로 이동, 이름 절단 후
말미 하이픈 잔존.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
엔진(jinsoo96/jermes `d29df3b`)을 흡수한다.
- agent: JermesAgent — remember→학습→측정→화해→보고를 한 사이클로
- memory: 증거로 등급을 매기는 기억(측정만이 trust 를 움직임, 모순은 벤치로 판정,
  자동 삭제 없음, 중립 감쇠로 경화 방지)
- constitution: never_learn 을 게이트가 집행. 에이전트는 자기 규약을 못 고친다
- gate: 규약 검사를 벤치 앞단에 배치(선택 인자라 기존 호출부 무영향)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
엔진(jinsoo96/jermes `78a59be`)의 검수 수정을 흡수한다.
- agent: 회상 렌더에서 본문 escape + 속성 전용 `_attr()`. stdlib quoteattr 는
  값에 큰따옴표가 있으면 작은따옴표로 감싸 `status="검증됨"` 이 문자 그대로 남아
  못 막는다(읽는 건 XML 파서가 아니라 LLM 이다).
- memory: 잡음 구간 대칭(min_gain 0.0→0.05), 수치 비교를 float 으로(0.8 vs 0.80
  오탐), 무판정 시 양쪽 이력에 사유 기록.
- portable: payload 안의 ``` 로 펜스가 조기 종료되던 것 — 내용에 맞춰 펜스 확장.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jinsoo96
jinsoo96 force-pushed the fix/backend-logger-nonserializable-metadata branch from 02f5930 to 0d24931 Compare August 5, 2026 12:01
무엇/왜:
BackendLogger._log 가 json.dumps(metadata) 를 default 없이 호출해, metadata
에 DB row 가 그대로 실려 오는 호출부(예: 배포상태 조회의 metadata=deploy_meta)
에서 datetime 을 만나면 TypeError 로 터졌다. except 가 이를 삼켜 로그만 남기고
넘어가므로 서비스는 안 죽지만 backend_logs 행이 통째로 사라져, 관리자 화면에서
해당 이력이 비어 보였다 (운영 로그에서 확인:
'Error logging backend data: Object of type datetime is not JSON serializable').

default=str 로 직렬화 불가 값(datetime/Decimal/UUID 등)을 문자열로 보존하고,
ensure_ascii=False 로 한글 metadata 가 유니코드 이스케이프로 저장되지 않게 한다.
DB 호출 이전 단계라 트랜잭션 영향은 없고, 성공 경로 동작도 그대로다.

회귀 테스트 3건 추가 (패치 전 datetime·한글 케이스 실패 확인).
@jinsoo96
jinsoo96 force-pushed the fix/backend-logger-nonserializable-metadata branch from 0d24931 to e7d7153 Compare August 5, 2026 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant