4.2 KiB
Executing unit: u2
📌 [Claude #4] Stage 3 Round #2 — u2 check_dormant_triggers 실행 완료
■ unit_executed: u2 — check_script
■ files_changed:
scripts/check_dormant_triggers.py(new, ~135 lines)
■ diff_summary
새 파일 1 개 생성. Stage 2 plan estimate_lines: 50 대비 실제 ~135 lines — 차이는 (a) module docstring + guardrail 명문화 (~20 lines), (b) _git_lines helper + collect_changed_files 의 working-tree + HEAD~1..HEAD 양쪽 수집 (rename 처리 포함), (c) _content_match 에서 invalid regex fallback (literal substring) 으로 false-positive 방지. 컨텐츠 단위 entry point 는 plan 그대로 단일 main() exit 0. scope-lock 외 파일 0.
핵심 동작 (Stage 1 EVIDENCE + Stage 2 guardrail 일치):
| 단계 | 동작 | 출처 |
|---|---|---|
| 1. registry 로드 | yaml.safe_load(DORMANT-TRIGGERS.yaml) → list of entries |
u1 산출물 (single source of truth) |
| 2. changed 수집 | git status --porcelain (working tree) ∪ git diff HEAD~1..HEAD --name-only |
issue body §P5-2 |
| 3. entry skip | manual_evidence_required: true OR followup_issue: set → None |
Stage 1 guardrails |
| 4. file-glob 매칭 | fnmatch.fnmatch(path, pattern) on POSIX-normalized path |
trigger.file_patterns |
| 5. content-regex 매칭 | re.search per pattern; invalid regex → literal substring fallback |
trigger.content_patterns |
| 6. alert 기록 | .orchestrator/dormant_alerts.json (UTC timestamp + registry path + alerts[]) |
issue body §P5-2 |
| 7. exit code | 항상 0 (informational only) | Stage 1 guardrails |
■ acceptance check (u2 only)
- standalone invocation:
python scripts/check_dormant_triggers.py→ exit 0 +.orchestrator/dormant_alerts.json생성 확인. 현재 working tree 에 dormant trigger 매칭 없음 →alerts: [](clean tree no-alert 케이스). - manual-evidence skip (smoke 검증):
check_entry(imp17, ['src/anything.py'])→None. IMP-17 의 3-cond gate (User GO + B4 + IMP-04/05) 는 human-only. - followup-linked skip (smoke 검증):
check_entry(imp20, ['anything'])→None. IMP-20 은 open issue #55 가 tracking. - phantom-file no-match (smoke 검증):
check_entry(imp16, ['src/imaginary_module.py'])→None. file_patterns glob match 만 되면 통과가 아니라 content_patterns (html_to_slide_mdx/edited_html_to_mdx/reverse_path) 까지 hit 해야 alert. false-positive 차단. - JSON schema:
{"generated_at": "<UTC isoformat>", "registry": "docs/architecture/DORMANT-TRIGGERS.yaml", "alerts": []}— u3 orchestrator helper 가 parse 가능한 stable shape.
Stage 2 plan tests: (test_check_script_clean_tree_no_alerts, test_check_script_writes_alerts_on_match, test_check_script_skips_manual_evidence_entries) 가 u4 에서 직접 assert 로 hook-up 가능한 surface (load_registry / collect_changed_files / check_entry / write_alerts 분리).
■ remaining_units (Stage 2 plan 순서 유지)
u3—orchestrator.py_check_dormant_triggers()helper + Stage 4→5 branch (P4a 미러; audit-only skip; informational supplement comment; never blocks)u4—tests/orchestrator_unit/test_dormant_triggers.py≥ 8 cases (IMP-# trigger 별 명명)u5—docs/architecture/PROJECT-INTENT-AND-GOVERNANCE.md§ 8 anti-patterns row 에 1 line 추가 (registry 가리키기)
■ follow_up_issue_candidates: 없음. u2 범위 내 scope-lock 외 axis 미발견.
■ guardrails 확인
- RULE 6 (commit scope only) — 본 turn 은 commit/push 없음 (Stage 3 contract). 파일 1 개만 작성. 부산물 (
.orchestrator/dormant_alerts.jsonsmoke 산출,.orchestrator/tmp/u2_smoke.py) 는 untracked + temp 영역, commit 대상 아님. - RULE 7 (no hardcoding) — 4 dormant 항목 list 를 script 가 hardcode 하지 않음. registry yaml 만 읽음. u1 ↔ u2 single-source 계약 유지.
- PZ-1 (AI=0 normal) — 본 unit deterministic only, LLM 호출 0.
- Stage 1 scope-lock —
scripts/check_dormant_triggers.py단일 파일, 다른 unit 영역 (orchestrator.py / tests/orchestrator_unit/ / governance doc) 미터치.
■ commit_sha: HEAD = 8c1e563 (Stage 3 진행 중, 미커밋 상태).
rewind_target: continue_same