주체: dartlab 자가개선 루프 (Observe·Pattern·Promote·Refine·Axis).
현재: Phase O 자동 기록 + Phase P/R/F/A 스크립트 + CLI (dartlab-coreloop) 구현. 초기 수동 운영.
방향: 3 개월 안정화 후 Phase P/R 점진 자동화. Phase A 는 영구 수동.
상위 사상: philosophy.md §6.
사람과 AI 가 서로 개선하는 양방향 루프. 사람이 엔진·블로그·지식을 만들면 AI 자산이 되고, AI 가 실행 중 발견한 개선이 엔진 docstring·블로그 frontmatter 로 사람 자산에 환류한다. 엔진 docstring 파일 하나가 다리. SSOT 단일.
| Phase | 이름 | 한 줄 명제 |
|---|---|---|
| O | Observe (실험) | 실사용 질문·tool 호출·응답·에러를 data/audit/ai-ask/YYYY-MM-DD.jsonl 에 기록 |
| P | Pattern (후보 감지) | 동일 (category, tool_sequence) N 회 성공 → docstring Guide append 초안 생성 |
| R | Promote (승격) | 사용자 --confirm → skill/docstring-* 브랜치 PR → CODEOWNERS 리뷰 merge |
| F | Refine (자가 개선) | 실패 신호 (error · extreme_flags · override 실패) → docstring "Caveats" PR |
| A | Axis (엔진 승격) | 반복 조합 M 회·30 일 숙성 → 공식 엔진 axis 신설 proposal (수동) |
src/dartlab/ai/runtime/audit.py::AuditCollector— v2 스키마 수집기 (신설 표준).src/dartlab/server/streaming.py::_AuditCollector— 서버 경로 (v2 필드 확장 호환 유지).
{dataDir}/audit/ai-ask/YYYY-MM-DD.jsonl (UTC). 한 줄 = 1 요청.
{
"schema_version": 2,
"ts": "2026-04-25T09:30:00.000000+00:00",
"request_id": "req-abc123",
"question": "삼성전자 수익성 분석해줘",
"question_hash": "sha256:a1b2c3d4e5f6...",
"category_hash": "FIN-profitability-KR-tech",
"stockCode_hint": "005930",
"provider": "oauth-codex",
"model": "gpt-5-codex",
"tool_calls": [
{"name": "analysis", "args": {...}, "args_hash": "...",
"ok": true, "error": null, "duration_ms": 1823,
"result_size_bytes": 4012, "overrides_used": null,
"extreme_flags": []}
],
"tool_sequence_hash": "seq:a1b2c3d4",
"override_calls": [
{"tool": "analysis", "override_keys": ["wacc"],
"trigger": "detectExtremeFlags:wacc>0.25", "succeeded": true}
],
"rounds": 2,
"chunk_len": 1823,
"error": null,
"violation": null,
"skill_used": null,
"duration_total_ms": 4521,
"judgment": {"verdict": null, "judged_at": null,
"judged_by": null, "pr_url": null}
}- I/O 실패 조용 무시 (응답 경로 보호).
args값 500 자 cap + 라인 4 KB 초과 시 요약본.DARTLAB_AUDIT_DISABLE=1환경변수 시 비활성.
scripts/audit/extract_skill_candidates.py
uv run dartlab-coreloop pattern --since 30d \
--min-repeat 3 --min-unique-questions 3 --min-chunk-len 400n >= min_repeatANDn_unique_q >= min_unique_questionsANDsuccess_rate == 1.0.error·violation있는 레코드 제외.
data/audit/candidates/{YYYY-MM-DD}-candidates.jsondata/audit/candidates/{YYYY-MM-DD}-draft.md(사람 검토용)
playbook고품질 bullet (quality >= 0.75ANDsuccess_count >= 5):--min-repeat완화 2 로.auditAnalysis/*.md"엔진 개선" 섹션:--include-audit-analysis(dry-run 강제).
--dry-run기본. PR 안 만듦.--sanitize: 공개 공유용 question 원문 제외.- polars streaming 불필요 (수천~수만 라인까지 Python json 반복 충분. 대용량 시 보강).
scripts/audit/promote_skill.py
uv run dartlab-coreloop promote \
--candidate data/audit/candidates/2026-04-25-candidates.json \
--id cand-2026-04-25-001 --confirm- candidate json 로드.
- 대상 파일의 Guide 섹션에 body append (없으면 말미 주석).
- hallucination 재현 테스트 (예시 질문 →
POST /api/ask, seq_hash 비교). - git 브랜치 생성 + 커밋 +
gh pr create --draft.
- 브랜치:
skill/docstring-{engine}-{axis-slug}-{YYYYMMDD}. - axis slug 매핑:
scripts/audit/_axis_slug.py::KOREAN_AXIS_SLUG. - 커밋 subject prefix:
[CORELOOP-R](3 중 auto-merge 차단 대상).
promote_skill.py가gh pr merge --auto호출 안 함..github/branch_protection.yml(별도 설정, 1 회): main 브랜치required_approving_review_count = 1..github/workflows/ai-policy.yml::block-coreloop-auto-mergejob —[CORELOOP-타이틀 +auto-merge라벨 동시 감지 시 라벨 제거 + fail.
append-only → git revert {sha} 한 번. 엔진 코드 불변 → behavior regression 불가.
scripts/audit/refine_skill.py
uv run dartlab-coreloop refine --since 30d --min-failures 2error필드 non-nullviolation필드 (P8 tool zero)chunk_len < 200tool_calls[].extreme_flagstriggeredoverride_calls[].succeeded == false
data/audit/counterexamples/{YYYY-MM-DD}-counterexamples.json
--exclude-types transient_network,rate_limit로 일시적 에러 제외.- Phase R 과 동일하게 append-only, auto-merge 금지, 재현 테스트.
scripts/audit/propose_axis.py — proposal md 만 생성. 엔진 코드 수정 X.
uv run dartlab-coreloop propose-axis \
--engine analysis --axis 수익성 \
--min-phase-r-merges 3 --min-phase-f-caveats 2 --min-age-days 30- Phase R merge 3+
- Phase F counterexample 2+
- 첫 R merge 로부터 30 일+
- proposal.md 생성 확인.
- 사용자 + AI pair 가 엔진 코드 설계:
core/overrides.pyoverride key 추가 (필요 시).{engine}/__init__.py새 axis enum 또는 공개 함수.- docstring 9 섹션 전부 (
ops/code.md규격). tests/unit/{engine}/test_axis_{slug}.py.
- 일반 engine PR (CORELOOP 마킹 없음 — 사람 판단 주).
- CODEOWNERS 리뷰 → merge.
엔진 axis 추가는 사상 수준 결정. override 오남용·축 난립 방지를 위해 사람 판단 필수.
- hook (실시간):
src/dartlab/story/publisher.py::publishReportFromCompany끝에src/dartlab/ai/persistence/blog_insights.py::upsert_ai_frontmatter_to_insights호출. - backfill (일괄):
uv run dartlab-coreloop backfill-blog --blog-root blog/ --confirmPhase P · R 본체가 담당. 추가로 고품질 playbook bullet 이 Phase P 2 차 근거.
scripts/audit/_parse_audit_analysis.py + extract_skill_candidates.py --include-audit-analysis (dry-run 강제).
scripts/audit/cleanup_knowledge_db.py
uv run python scripts/audit/cleanup_knowledge_db.py # dry-run
uv run python scripts/audit/cleanup_knowledge_db.py --confirm # 실제 정리insights(source="live")전량 drop (검증 게이트 없이 축적분).insights(source="audit")중 md 파일 부재 레코드 drop.- 남은 audit 레코드에
evidence_ref = 'audit:data/dart/auditAnalysis/{code}.md',quality_gate = 'migration'주입. playbook→quality >= 0.75 AND success_count >= 5만 유지.executions30 일 이전 drop +question→question_hash치환.- 아카이브:
data/ai/knowledge/_archive/{YYYY-MM-DD}-pre-cleanup.sqlite.
saveInsightFromResponse→response_length >= 500 AND grade in {P,T} AND stockCode present게이트.curate()playbook 쓰기 →quality < 0.5면 매월 auto-prune 대상.
scripts/audit/sanitize_audit.py
# check — 민감 토큰 리포트만 (파일 미작성)
uv run dartlab-coreloop sanitize --check data/audit/ai-ask/
# hash — question → question_hash, 공개 공유용
uv run dartlab-coreloop sanitize --in data/audit/ai-ask/ --out /tmp/sanitized --mode hash
# drop — question 삭제
uv run dartlab-coreloop sanitize --in data/audit/ai-ask/ --out /tmp/sanitized --mode drop
# mask — 종목명·이메일·URL 마스킹 (블로그용)
uv run dartlab-coreloop sanitize --in data/audit/ai-ask/ --out /tmp/sanitized --mode mask원본 jsonl 은 절대 덮어쓰지 않음.
Phase R PR 후에도 9 섹션 규격 유지 체크: tests/unit/test_docstring_shape.py (W-J 에서 신설 예정).
- audit jsonl 가 GB 단위로 커질 때 polars streaming (
pl.scan_ndjson+collect(streaming=True)) 사용. core.memory.check_memory_and_gc호출 지점 유지.
| 작업 | 사용자 | AI pair | CI |
|---|---|---|---|
| Phase O 기록 | — | — | A |
| Phase P 집계 | A | C | I |
| Phase R PR | A | R | I |
| Phase F PR | R | A | I |
| Phase A 승격 | A | C | — |
| sanitize 공유 | A | — | — |
| KnowledgeDB 정리 | A | C | — |
R=Responsible · A=Accountable · C=Consulted · I=Informed.
- M0–M1: 전부 수동. 사용자가 주 1 회
dartlab-coreloop pattern실행. - M1–M3:
.github/workflows/coreloop-pattern.ymlnightly cron. candidate/draft 자동 생성, PR 은 수동. - M3+ (안정화 지표 충족 시): tier 1 (Guide 섹션 append 만) draft PR 자동 생성. merge 는 계속 수동.
안정화 지표: Phase R 연속 clean merge 30 회 · 직전 3 개월 revert 0 · docstring shape 회귀 0.
구현: src/dartlab/cli/coreloop.py. pyproject.toml [project.scripts] 등록.
dartlab-coreloop status # 현황 요약
dartlab-coreloop pattern --since 7d # Phase P
dartlab-coreloop refine --since 30d # Phase F
dartlab-coreloop promote --candidate <path> --id <id> --confirm # Phase R
dartlab-coreloop propose-axis --engine analysis # Phase A
dartlab-coreloop sanitize --mode hash # 민감정보 마스킹
dartlab-coreloop verify --candidate <path> --id <id> # 재현 테스트
dartlab-coreloop backfill-blog --blog-root blog/ --confirm # 블로그 → insights- philosophy.md §6 — 5 Phase 사상 근거
- skills.md — docstring = skill 규약
- code.md — docstring 9 섹션 규격 (Guide · When · How · Verified · Examples)
- ai.md §11 — audit 10 질문 (별개 사람 품질 검증)
- api-contract.md — 공개 API 추가 규칙
- Phase A 자동화 (엔진 axis 를 코드 생성) — 사상 수준 결정이라 수동 강제.
- Phase R PR 을
gh pr merge --auto로 머지 — 3 중 방어 우회 시도. - audit jsonl 공개 전 sanitize 누락 — 사용자 질문 원문 유출.
- Phase P 집계에서 error/violation 레코드 미제외 — 실패 패턴을 "성공 skill" 로 오승격.