fix(sync): manifest.exported_at 제거 — no-op push 회피
dogfood: 노트 변경이 0건이어도 자동 sync 가 매번 commit + push 를 생성. 원인은 manifest.json 의 exported_at timestamp 가 매 export 마다 갱신되어 git diff 가 항상 1줄 발생. 해결: composeManifest 의 exportedAt 입력 제거 + 출력 JSON 에서 필드 삭제. 이 필드는 ImportService 가 read 하지 않고 UI 표시도 없는 cosmetic 정보였음. 이제 노트 변경 있을 때만 commit/push 가 일어난다. 회귀 테스트: 같은 input 으로 두 번 호출 시 stable 출력 invariant 추가. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -136,7 +136,6 @@ export class ExportService {
|
||||
totalBytes += Buffer.byteLength(indexJsonl, 'utf8');
|
||||
|
||||
const manifest = composeManifest({
|
||||
exportedAt: this.now().toISOString(),
|
||||
noteCount: notes.length,
|
||||
mediaCount
|
||||
});
|
||||
|
||||
@@ -253,14 +253,15 @@ export function composeIndexJsonl(
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export function composeManifest(input: {
|
||||
exportedAt: string;
|
||||
noteCount: number;
|
||||
mediaCount: number;
|
||||
}): string {
|
||||
// exported_at 필드 의도적 제외 — note 변경 없이도 git sync 가 매 호출마다
|
||||
// timestamp 갱신 1줄 commit 을 만들어 history 노이즈와 불필요한 push 유발.
|
||||
// import path 는 inkling_export_version 만 read 하므로 안전.
|
||||
return JSON.stringify(
|
||||
{
|
||||
inkling_export_version: 1,
|
||||
exported_at: input.exportedAt,
|
||||
note_count: input.noteCount,
|
||||
media_count: input.mediaCount
|
||||
},
|
||||
|
||||
@@ -230,16 +230,22 @@ describe('composeIndexJsonl', () => {
|
||||
});
|
||||
|
||||
describe('composeManifest', () => {
|
||||
it('emits pretty JSON with required fields', () => {
|
||||
it('emits pretty JSON with required fields (timestamp-free)', () => {
|
||||
const m = composeManifest({
|
||||
exportedAt: '2026-04-26T00:00:00.000Z',
|
||||
noteCount: 42,
|
||||
mediaCount: 17
|
||||
});
|
||||
const obj = JSON.parse(m);
|
||||
expect(obj.inkling_export_version).toBe(1);
|
||||
expect(obj.exported_at).toBe('2026-04-26T00:00:00.000Z');
|
||||
expect(obj.note_count).toBe(42);
|
||||
expect(obj.media_count).toBe(17);
|
||||
// exported_at 필드 제거 — sync git history noise 방지.
|
||||
expect(obj.exported_at).toBeUndefined();
|
||||
});
|
||||
|
||||
it('두 번 호출 결과 stable (sync no-op invariant — 같은 input 이면 git diff 0)', () => {
|
||||
const a = composeManifest({ noteCount: 5, mediaCount: 2 });
|
||||
const b = composeManifest({ noteCount: 5, mediaCount: 2 });
|
||||
expect(a).toBe(b);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user