feat: Self-Evolving Digital Employee OS P0~P6 + 캘린더 충돌 게이트
신뢰성 코어 (P1~P2): - Requirement Graph: 업무 유형(회의록/시장조사/업무조사/일정) 필수 요소 주입 + 커버리지 hook - Confidence Engine(0~100 결정론적) / Escalation Engine(검토 요청) / Epistemic Guard(모름·추정·확실 3분류) - Provenance: citationTrace 에 출처 수정일·오래됨 경고 - Critic Loop: 문제 신호 turn 만 LLM 검수 1회 + 보완 카드 성장 루프 (P3): - Gap Detector(Requirement-Knowledge) / Need Engine(30/25/20/15/10 공식) / Knowledge Inventory - Learning Queue(proposed 전용 병합 — 승인은 사람만) / Decision Journal / Reflection 기록 - 반복 누락 요소(3회+)는 다음 turn 체크리스트에 자동 강조 (T5 루프) 지식 운영 (P4) + 기억 (P5) + 학습 실행 (P6): - Knowledge Validation + Belief Revision(중복 reject·충돌 시 update/add 권고) - Knowledge Decay(분야별 반감기 감사) / Knowledge Debt(blocked x impact) - Organizational Memory(.astra/organization.md 상시 주입) - Research Agent(approved 큐 -> 조사 브리프+추정 라벨 초안+Validation 게이트 -> proposals/) - Skill Score(전/후반 추세) + Success Pattern DB(전요소충족+확신도90+ 자동 적재) 병렬 트랙: - 캘린더 충돌 게이트: conflictCheck + 구조화 이벤트 캐시 + create_calendar_event 차단(force 는 사용자 승인 후) - Task Eval Harness: 회의록 골든셋 자동 채점 명령 + 성장 리포트/학습 큐/노후 점검 명령 신규 모듈 17종(src/intelligence/), VS Code 명령 5종, 설정 11종, 테스트 +89건(전체 508 통과). 설계 문서: docs/SELF_EVOLVING_OS_MASTER_PLAN.md Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,32 @@ import { RetrievalChunk } from './types';
|
||||
export interface CitationTraceOptions {
|
||||
/** 답변 끝 *출처 한 줄* 형식. 'tail' 만 v1 지원. */
|
||||
format: 'tail';
|
||||
/**
|
||||
* Provenance 표시 (Self-Evolving OS Phase 2 / Track 1-4) — 상위 출처의
|
||||
* 최종 수정일·score 를 블록에 노출하고, 오래된 출처 사용 시 모델이 답변에
|
||||
* 그 사실을 명시하게 지시. 기본 true.
|
||||
*/
|
||||
provenanceEnabled: boolean;
|
||||
/** 이 일수보다 오래된 출처는 "오래됨" 으로 분류. 기본 180일. */
|
||||
staleAfterDays: number;
|
||||
/** Provenance 에 나열할 상위 출처 수. 기본 5. */
|
||||
provenanceTopCount: number;
|
||||
/** 테스트 주입용 현재 시각 (epoch ms). 기본 Date.now(). */
|
||||
nowMs?: number;
|
||||
}
|
||||
|
||||
const DEFAULT_OPTIONS: CitationTraceOptions = {
|
||||
format: 'tail',
|
||||
provenanceEnabled: true,
|
||||
staleAfterDays: 180,
|
||||
provenanceTopCount: 5,
|
||||
};
|
||||
|
||||
function fmtDate(epochMs: number): string {
|
||||
const d = new Date(epochMs);
|
||||
const mm = String(d.getMonth() + 1).padStart(2, '0');
|
||||
const dd = String(d.getDate()).padStart(2, '0');
|
||||
return `${d.getFullYear()}-${mm}-${dd}`;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,6 +57,7 @@ export function buildCitationTraceBlock(
|
||||
options: Partial<CitationTraceOptions> = {},
|
||||
): string {
|
||||
if (!chunks || chunks.length === 0) return '';
|
||||
const opts: CitationTraceOptions = { ...DEFAULT_OPTIONS, ...options };
|
||||
|
||||
const lines: string[] = [];
|
||||
lines.push('[CITATION TRACE]');
|
||||
@@ -44,6 +71,32 @@ export function buildCitationTraceBlock(
|
||||
lines.push('3. 일반 모델 지식만 사용했다면: *출처: 모델 지식 (검색 출처 미사용)*');
|
||||
lines.push('4. 답변이 검증 가능하도록 — 사용자가 그 파일을 열면 답변 근거를 확인할 수 있어야.');
|
||||
lines.push('5. *출처:* 라인은 답변 *맨 끝* 한 번만 — 본문 중간에 흩어 놓지 말 것.');
|
||||
|
||||
// ─── Provenance — 출처 신선도·신뢰도 메타데이터 (Track 1-4) ───
|
||||
// 목적: "어떤 지식 때문에 이 결론이 나왔는가" 역추적 + 오래된 지식 기반 답변 표시.
|
||||
if (opts.provenanceEnabled) {
|
||||
const now = opts.nowMs ?? Date.now();
|
||||
const staleMs = opts.staleAfterDays * 24 * 60 * 60 * 1000;
|
||||
const top = chunks
|
||||
.filter((c) => c.source !== 'brain-trace')
|
||||
.sort((a, b) => b.score - a.score)
|
||||
.slice(0, opts.provenanceTopCount);
|
||||
const withMeta = top.filter((c) => typeof c.metadata?.lastUpdated === 'number');
|
||||
if (withMeta.length > 0) {
|
||||
lines.push('');
|
||||
lines.push('[출처 메타데이터 — Provenance]');
|
||||
for (const c of withMeta) {
|
||||
const updated = c.metadata.lastUpdated as number;
|
||||
const isStale = now - updated > staleMs;
|
||||
const staleTag = isStale ? ` ⚠️오래됨(${opts.staleAfterDays}일+)` : '';
|
||||
lines.push(`- \`${c.title || '(제목 없음)'}\` — 수정일 ${fmtDate(updated)}, score ${c.score.toFixed(2)}${staleTag}`);
|
||||
}
|
||||
if (withMeta.some((c) => now - (c.metadata.lastUpdated as number) > staleMs)) {
|
||||
lines.push('⚠️오래됨 출처를 핵심 근거로 사용하면 답변에 "출처가 오래되어 현재와 다를 수 있음" 을 명시할 것.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lines.push('[/CITATION TRACE]');
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user