feat: v2.2.173-193 — 4인 팀 운영 슬래시 13개 + ASTRA 검증 엔진 6종

4인 팀 운영 슬래시 (v2.2.173~189):
- 일과 리듬: /morning, /evening, /weekly, /standup
- 트래커 (event-sourced .astra/*.jsonl): /runway, /customers, /hire
- 작업·결정: /task, /blocked, /onesie, /decisions
- 외부 출력: /draft, /feedback
- 분석: /cohort (MoM 추세)

ASTRA 추론·검색 엔진 (v2.2.183~192):
- v2.2.183 Conflict Surface — scoring.conflictSeverity 를 [CONFLICT WARNINGS] 블록으로
  서피스 + 교차-문서 발산(Jaccard) 감지
- v2.2.184 Chain-of-Verification — [VERIFICATION CHECKLIST] 답변 작성 전 그라운딩 자기 점검
  (instructional, strictMode 옵션)
- v2.2.185 Actionability Scoring — 최근 슬래시 명령 + 열린 파일 신호로 검색 결과 재가중
- v2.2.186 Temporal Markers + Distillation Loop — LongTerm/Episodic 만료 필터 +
  30일+ stale episode → LongTerm 'episode-digest' 승급 (수동 /memory distill + 세션 종료 자동)
- v2.2.187 Hierarchical Context Window + LLM Semantic Re-rank — 3-level 추상도 매칭
  + 토큰 예산 통과 후 LLM 1회로 의도-부합 재정렬 (opt-in)
- v2.2.190 Intent Clarification + Citation Trace — 모호 차원 감지 시 역질문 우선
  + 답변 끝 사용 출처 한 줄 정리
- v2.2.191 Post-hoc Self-Check — 답변 완료 후 별도 LLM 호출 1회로 답함/그라운딩/모순 평가,
  footer 한 줄로 표시 (opt-in, semantic re-rank 와 같은 안전 fallback 패턴)
- v2.2.192 Terminology Dictionary — .astra/glossary.md 사용자 편집 파일 + Term Check
  지침 통합 + /glossary init/path/reload
- v2.2.193 /help — 카테고리별 명령 목록 + 6종 verification 블록 현재 on/off

신규 모듈:
- src/retrieval/{conflictBlock,coveBlock,actionabilityScoring,hierarchicalLevel,
  semanticRerank,intentClarification,citationTrace,terminologyBlock}.ts
- src/memory/distillation.ts + types.ts 에 expiresAt/promoted/episode-digest 추가
- src/agent/postHocSelfCheck.ts
- src/features/{customers,feedback,hire,runway}/*.ts (event-sourced stores)

ASTRA 검증 5종 자동 주입 (buildAstraModeSystemPrompt, casual 모드 제외):
[INTENT CLARIFICATION GUIDANCE] (답변 시작 전) → [TERMINOLOGY DICTIONARY] +
[CONFLICT WARNINGS] + [VERIFICATION CHECKLIST] (작성 중) → [CITATION TRACE] (끝)
+ 6번째: Post-hoc Self-Check footer (답변 완료 후, opt-in)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-29 16:05:30 +09:00
parent f3439ddad5
commit 990ea0ae5f
46 changed files with 7172 additions and 136 deletions
+137
View File
@@ -0,0 +1,137 @@
/**
* Terminology Dictionary — 프로젝트 표준 용어집을 시스템 프롬프트에 주입.
*
* 사용자 제안: "표준 표기 강제 + 답변 내 표기 일관성 검증". 예: `runway` vs `런웨이`,
* `P-Reinforce` vs `p-reinforce`, `Chronicle` vs `크로니클`.
*
* 설계 — 사용자 편집 markdown 파일:
* - 위치: `<workspace>/.astra/glossary.md`
* - 형식: 자유 markdown. ASTRA 는 *형식을 강제하지 않고* 통째로 주입
* - 권장 컨벤션: H2/H3 섹션으로 표준 표기 / 영-한 컨벤션 / 금지 용어 등 그룹핑
*
* 시스템 프롬프트 블록 `[TERMINOLOGY DICTIONARY]`:
* - 글로서리 본문 + Term Check 지침 (#1 typo/용어 self-check 사용자 제안 통합)
* - 답변 작성 시 표준 표기 우선 + 답변 직전 자기 점검 + 새 용어 도입 시 명시
*
* 캐시: 파일 mtime 기반 — 매 turn 디스크 read 안 함.
*/
import * as fs from 'fs';
import * as path from 'path';
import * as vscode from 'vscode';
const DEFAULT_GLOSSARY_REL_PATH = '.astra/glossary.md';
/** mtime-keyed cache — 사용자가 편집할 때만 다시 읽음. */
const _cache = new Map<string, { mtime: number; content: string }>();
export function getGlossaryFilePath(relPath: string = DEFAULT_GLOSSARY_REL_PATH): string | null {
const folders = vscode.workspace.workspaceFolders;
if (!folders || folders.length === 0) return null;
return path.join(folders[0].uri.fsPath, relPath);
}
function readGlossary(relPath: string): string {
const fp = getGlossaryFilePath(relPath);
if (!fp) return '';
try {
if (!fs.existsSync(fp)) return '';
const st = fs.statSync(fp);
const cached = _cache.get(fp);
if (cached && cached.mtime === st.mtimeMs) return cached.content;
const content = fs.readFileSync(fp, 'utf-8').trim();
_cache.set(fp, { mtime: st.mtimeMs, content });
return content;
} catch {
return '';
}
}
export function clearGlossaryCache(): void {
_cache.clear();
}
export interface TerminologyBlockOptions {
/** Glossary 파일 상대 경로. 기본 '.astra/glossary.md'. */
relPath: string;
/** 본문 최대 길이 (chars). 너무 큰 글로서리는 시스템 프롬프트 비대 — cap. 기본 4000. */
maxBodyLength: number;
/** 길이 초과 시 잘릴 안내 표시 여부. */
showTruncationNote: boolean;
}
export const DEFAULT_TERMINOLOGY_OPTIONS: TerminologyBlockOptions = {
relPath: DEFAULT_GLOSSARY_REL_PATH,
maxBodyLength: 4000,
showTruncationNote: true,
};
export function buildTerminologyBlock(options: Partial<TerminologyBlockOptions> = {}): string {
const opts: TerminologyBlockOptions = { ...DEFAULT_TERMINOLOGY_OPTIONS, ...options };
const raw = readGlossary(opts.relPath);
if (!raw) return ''; // 파일 없음 → 블록 안 만듦 (no-op)
let body = raw;
let truncated = false;
if (body.length > opts.maxBodyLength) {
body = body.slice(0, opts.maxBodyLength);
truncated = true;
}
const lines: string[] = [];
lines.push('[TERMINOLOGY DICTIONARY]');
lines.push('프로젝트 표준 용어집. 답변 생성 시 다음 표기·컨벤션을 *최우선* 으로 사용.');
lines.push('');
lines.push('---');
lines.push(body);
if (truncated && opts.showTruncationNote) {
lines.push('');
lines.push(`_…(글로서리 ${raw.length - opts.maxBodyLength}자 잘림 — 핵심 용어를 앞쪽에 배치해 주세요)_`);
}
lines.push('---');
// Term Check 지침 — 사용자 제안 #1 (typo/용어 self-check) 통합.
lines.push('');
lines.push('[Term Check — 답변 직전 자기 점검]');
lines.push('1. **표준 표기 우선**: 위 용어가 답변에 등장하면 *글로서리의 표기를 그대로* 사용. 변형·번역 임의 적용 금지.');
lines.push('2. **표기 흔들림 방지**: 같은 용어를 한 답변 안에서 *동일 표기* 로 일관 사용 (예: "Chronicle" 과 "크로니클" 섞지 말 것).');
lines.push('3. **새 용어 도입 시**: 글로서리에 없는 고유 명사·약어 처음 사용 시 *"새 용어: X"* 라고 한 번 명시.');
lines.push('4. **금지 표기 검증**: 답변 직전, 글로서리의 *금지·비추* 항목이 답변에 들어가지 않았는지 검토. 들어갔으면 *재작성*.');
lines.push('5. **모르겠으면 글로서리**: 표기 확신 없을 때 "글로서리에 없어 일반 표기 사용" 한 줄 명시 후 진행.');
lines.push('[/TERMINOLOGY DICTIONARY]');
return lines.join('\n');
}
/**
* 글로서리 파일 작성 도우미 — 처음 사용자가 만들 때 권장 컨벤션 템플릿.
* 슬래시 명령 `/glossary init` 등에서 호출.
*/
export const GLOSSARY_TEMPLATE = `# 프로젝트 용어집
ASTRA 가 답변 시 표준 표기로 사용. 사용자가 자유롭게 편집 가능.
파일 저장 후 다음 채팅 turn 부터 자동 반영.
## 표준 표기
- **ASTRA** (X: astra, Astra 외) — 본 VS Code extension 이름
- **P-Reinforce v3.0** (X: p-reinforce, p reinforce) — 지식 압축 규칙
- **Chronicle ADR** (X: chronicle, ADR 단독) — 의사결정 기록
## 영-한 표기 컨벤션
- Performance → 성능
- Bug → 버그
- Memory → 메모리
## 금지·비추 표현
- ❌ "절대적", "반드시" (단정적 표현 — 정책 충돌 위험)
- ❌ "에이전트가 알아서" (그라운딩 위반)
- ❌ 한·영 깨짐 (예: "결ently", "p-rein동")
## 슬래시 명령 표기
원문 그대로 — 한국어 번역 금지:
- /runway, /customers, /hire, /morning, /evening, /weekly, /cohort, /memory, /glossary
`;