fix(setup): 페이로드 .DS_Store 제외 + 동일 버전 콘텐츠 드리프트 재싱크#427
Conversation
JeremyDev87
left a comment
There was a problem hiding this comment.
딸깍 크로스리뷰 — PR #427
- Head SHA:
4740c3d278e8a795ae60c11722af6cca90e13130 - Scope:
bin/lib/local-payload.mjs,bin/lib/setup.mjs,bin/lib/setup/install-transaction.mjs,scripts/test-setup.mjs(+108/−8) - Wiki preflight: lightweight-skip — 설치기 내부 툴링 변경으로 조직 wiki 파생 주장 없음(근거: repo 소스·CI·로컬 실행).
CI / checks
8/8 terminal green — CodeQL, Analyze JavaScript, Budget isolation gate, Dependency Review, Verify package (Node 18/20/22/24).
Validation evidence (독립 재검증)
npm test69/69 (신규 2건:.DS_Store제외, 동일버전 드리프트 재싱크).- e2e: 실소스
.DS_Store1개 존재 → 설치본/manifest 0개(파일 55→54). - e2e: 동일버전 드리프트 시
--dry-run재싱크 예고 + 실행 시 백업→재싱크→SKILL.md 소스 바이트 복원; 드리프트 없으면 정상 skip. - 독립 리뷰어(적대적) 및 부모 코드 재검증:
cp필터는 파일 전용이라 서브트리/루트 skip 없음, 드리프트 분기는 backup/replace로 정상 fallthrough(데이터 손실·이중 백업 없음), 신규 테스트는 fix를 실제로 검증.
Blocking findings: 0
인라인 Low 1건(드리프트 extra-file 비대칭, pre-existing) — 아래 인라인 코멘트. 비블로커.
구분
- CI/check: green(터미널).
- Formal review/branch protection: 작성자 PR이라 형식 APPROVE 불가 → COMMENT 이벤트로 게시.
- Merge blocker: 없음.
- Human action: Low finding 반영 여부 결정 후, 드래프트 해제(Ready for review) + 수동 머지. (자동 머지 금지)
결론: ready for manual merge (블로커 없음, CI green). 자동 머지·자가 승인하지 않음.
4740c3d to
0afd624
Compare
설치기가 payload를 파일시스템 복사로 긁어 .DS_Store가 설치본과 manifest에 섞여 들어가고, skip 판정이 .installed-version만 비교해 콘텐츠가 바뀌어도 같은 버전이면 no-op이 되던 두 문제를 함께 고친다. listPayloadFiles 단일 파일워크에 junk 필터를 두어 copy·manifest·checksum이 같은 파일 집합을 보고, skip 경로에 payloadChecksum 기반 드리프트 검사를 추가해 status --local이 이미 stale로 보던 케이스를 설치 경로(및 --dry-run 프리뷰)도 자동 재싱크한다. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Ultraworked-With: claude-opus-4-8[1m] User-Request: ddalggak setup의 .DS_Store 정크 제외와 동일버전 콘텐츠 드리프트 재싱크
0afd624 to
40abeae
Compare
JeremyDev87
left a comment
There was a problem hiding this comment.
딸깍 크로스리뷰 — PR #427 · 수렴(최종 라운드)
- Head SHA:
40abeaef29fd8a9d909d372884645a5fa2600b2b - Scope: 5파일 (+147/−13) —
local-payload,setup,install-transaction,status/install-parity,test-setup - Wiki preflight: lightweight-skip(설치기 내부 툴링; 조직 wiki 파생 주장 없음).
반복 루프 요약 (수정→amend→force push→재리뷰)
- R0 (
4740c3d): Low 1 — 드리프트가 extra-file 미감지 → 수정(payloadDrifted확장). - R1 (
0afd624): Low 2 —allowedExtra중복(setup vs status) → 수정(INSTALL_METADATA_NAMES단일 상수 hoist). - R2 (
40abeae): 중복 Low RESOLVED, 신규 결함 0. 잔존은 pre-existing/out-of-scope Low 1건뿐.
CI / checks
8/8 terminal green (CodeQL·Analyze JS·Budget isolation·Dependency Review·Verify package Node 18/20/22/24). mergeState CLEAN.
Validation evidence
npm test70/70 (신규 3건:.DS_Store제외, 동일버전 콘텐츠 드리프트, extra-file 드리프트).- e2e: setup(
re-sync)와status --local(stale)이 clean/.DS_Store-only/changed/missing/extra 5케이스에서 일치. - 독립 적대적 리뷰어 2회 + 부모 코드 재검증: cp 필터 안전, 드리프트 분기 backup/replace 정상 fallthrough(무손실·무이중백업), 무한 재싱크 없음, hoist는 byte-for-byte 동작 보존.
Blocking findings: 0
잔존 advisory (Low · pre-existing · out-of-scope, 미반영)
bin/lib/setup/install-transaction.mjs의 backfillInstalledManifest(~L54, 이 PR 미변경 코드): 손상된 .installed-manifest.json이 있고 payload 바이트·버전은 정상일 때, status --local은 stale(install-parity installedManifestParseError)로 재설치를 안내하지만 setup은 payloadDrifted=false + backfill이 '존재하지만 손상'을 재작성하지 않아 Already up to date로 끝나 status와 계속 어긋납니다. 이 PR과 무관하며 두 독립 리뷰어가 out-of-scope 판정 → 이번 스코프(.DS_Store + 드리프트)에서 반영하지 않음. 원하시면 별도 PR로 backfill을 'malformed도 재작성'으로 확장(테스트 포함) 가능.
구분
- CI/check: green(터미널).
- Formal review/branch protection: 작성자 PR → GitHub 형식 APPROVE 불가 → COMMENT 이벤트. 실질 승인 신호 = blocker 0 + CI green + 신규 actionable 0.
- Merge blocker: 없음.
- Human action: 드래프트 해제(Ready) + 수동 머지(주인님). 자동 머지·자가 승인 안 함.
결론: 수렴 — ready for manual merge. 반복 루프가 0 blocker / 0 신규 actionable / CI green로 안정화됨.
무엇을
ddalggak setup설치기의 두 결함을 함께 수정합니다..installed-manifest.json에 섞여 들어가던.DS_Store(macOS 정크) 제외.installed-version만 비교하던 skip 판정에 콘텐츠 체크섬 드리프트 검사 추가왜
.gitignore에 있어도(추적 안 됨).DS_Store가 그대로 설치본·manifest에 포함됐습니다.setup이 no-op이 되는 함정이 있었습니다. 로컬 재동기화에 매번--force가 강제됐습니다. (status --local은 이미 이 케이스를stale로 올바르게 판정하고 있어, 설치 경로만 정의가 어긋나 있었습니다.)어떻게
listPayloadFiles(copy·manifest·checksum이 공유하는 단일 파일워크)에isIgnoredPayloadEntry필터를 두어 세 소비자가 같은 파일 집합을 보게 함.stageInstall의cp에도 동일 basename 필터 적용.payloadDrifted(sourceRoot, installedRoot)헬퍼 추가 — 소스 파일 목록 기준으로 체크섬 비교(설치 메타데이터 무시,status --local과 동일 정의).installSkillPayloadskip 분기와setup --dry-run프리뷰가 같은 버전이라도 드리프트 시 재싱크하도록 변경.--force는 기존대로 무조건 재설치.검증
npm test— 69/69 통과 (신규 2건 포함:.DS_Store제외, 동일버전 드리프트 재싱크).DS_Store존재): 설치본.DS_Store0개, manifest 0개, 파일 55→54--dry-run"Would re-sync", 실행 시 감지→백업→재싱크→SKILL.md 소스 바이트 복원, 드리프트 없는 재실행은 정상 skip제외 범위 (Non-goals)
.DS_Store외 다른 junk 패턴 일반화는 하지 않음(관측된 문제에 한정,IGNORED_PAYLOAD_NAMES로 확장 용이).Closes미포함.