# task-2662 — ANU v3.1 Codex Micro Refinement Loop Core Phase 1

- **status**: `ANU_V3_1_CODEX_MICRO_REFINEMENT_LOOP_CORE_PR_READY`
- **chair_authorization_id**: `CHAIR-AUTH-V3-1-CODEX-MICRO-LOOP-20260525-JJONGS-START-001`
- **base**: `origin/main @ 2752182a` (PR #148 merged)
- **branch**: `task/task-2662-dev2`
- **worktree**: `/home/jay/workspace/.worktrees/task-2662-dev2`
- **auto-merge**: `0` (label not applied — forbidden 5)
- **production write**: `0`
- **dev bot dispatch**: `0`
- **forbidden_action_count**: `0`

## SCQA

**Situation**: ANU v3.1 (Codex micro refinement loop) was 0% implemented; ANU master spec section 5.4 mandates an automatic refinement loop that converges Codex findings without 회장 copy-paste intervention.

**Complication**: Naive automation would re-enable dev bot dispatch, GitHub write, or production mutation. Phase 1 must deliver core loop logic only — every forbidden capability stays disabled.

**Question**: How do we deliver the Core module + schemas + 10 regression fixtures + GO_READY/HOLD packets without touching dispatch.py, hooks/*, settings.json, finish-task.sh, axis 1/2/3, or any real-write surface?

**Answer**: A pure-logic, no-IO module (`utils/anu_codex_micro_refinement_loop.py` + `utils/codex_cc_decision_loop.py`) wired to 4 new JSON schemas and exercised by 10 regression fixtures. All 8 safety_gates trigger immediate HOLD_FOR_CHAIR; `changed_files` are enforced against `allowed_write_paths`; safe micro refinement rounds carry no hard cap (ANCHOR-3).

## 보고 9 (task md verbatim 1:1)

### 1. PR 번호

대기 — `gh pr create` 실행 결과는 본 commit 직후 별도 evidence (`memory/events/task-2662.pr-number.txt`)로 첨부.

### 2. changed_files

```
schemas/anu_v3_1_micro_refinement_target.json                                          (new)
schemas/anu_v3_1_micro_refinement_result.json                                          (new)
schemas/anu_v3_1_go_ready_packet.json                                                  (new)
schemas/anu_v3_1_hold_for_chair_packet.json                                            (new)
utils/codex_cc_decision_loop.py                                                        (new)
utils/anu_codex_micro_refinement_loop.py                                               (new)
tests/anu_codex_micro_refinement_loop/__init__.py                                      (new)
tests/anu_codex_micro_refinement_loop/conftest.py                                      (new)
tests/anu_codex_micro_refinement_loop/test_regression_10.py                            (new)
memory/events/task-2662.anu-v3-1-codex-micro-refinement-loop-core-result-260525.json   (new)
memory/reports/task-2662.md                                                            (new)
memory/events/task-2662.done                                                           (new, post-finalize)
```

All 12 paths lie inside `allowed_write_paths`. Zero forbidden_paths touched.

### 3. 구현 모듈

- `utils/anu_codex_micro_refinement_loop.py` — Core convergence loop driver (`run_micro_refinement`, `validate_target`, `enforce_allowed_write_paths`, GO_READY/HOLD packet builders, 8 safety_gates enforcement, hard cap 0).
- `utils/codex_cc_decision_loop.py` — Codex verdict translator (`evaluate`, `CodexDecision`) used by the loop to fold safety probes into `auto_execute_allowed`.

Both modules are pure Python with no IO, no network, no GitHub, no dispatch.

### 4. schema / fixture / test 목록

Schemas (4):

- `schemas/anu_v3_1_micro_refinement_target.json` (section 5.5)
- `schemas/anu_v3_1_micro_refinement_result.json` (section 5.6)
- `schemas/anu_v3_1_go_ready_packet.json` (section 5.7)
- `schemas/anu_v3_1_hold_for_chair_packet.json` (section 5.8)

Fixtures: every fixture is inline in `test_regression_10.py` via the `_target()` and `_round()` helpers (no external JSON inputs needed).

Tests (12 total, 10 task-mandated regressions + 2 helper):

- `test_R1_safe_document_refinement_go_ready`
- `test_R2_pass_with_recommendations_go_ready`
- `test_R3_critical_7_finding_hold_for_chair`
- `test_R4_permission_expansion_hold_for_chair`
- `test_R5_github_write_required_hold_for_chair`
- `test_R6_forbidden_write_target_touch_hold_for_chair`
- `test_R7_scope_expansion_hold_for_chair`
- `test_R8_allowed_write_paths_violation_hold_for_chair`
- `test_R9_repeated_safe_rounds_allowed_no_hard_cap`
- `test_R10_go_ready_packet_contains_chair_command`
- `test_helper_enforce_allowed_write_paths_basic`
- `test_target_validation_rejects_max_rounds_nonzero`

### 5. regression 결과 (10/10 개별)

```
R1  PASS  test_R1_safe_document_refinement_go_ready
R2  PASS  test_R2_pass_with_recommendations_go_ready
R3  PASS  test_R3_critical_7_finding_hold_for_chair
R4  PASS  test_R4_permission_expansion_hold_for_chair
R5  PASS  test_R5_github_write_required_hold_for_chair
R6  PASS  test_R6_forbidden_write_target_touch_hold_for_chair
R7  PASS  test_R7_scope_expansion_hold_for_chair
R8  PASS  test_R8_allowed_write_paths_violation_hold_for_chair
R9  PASS  test_R9_repeated_safe_rounds_allowed_no_hard_cap
R10 PASS  test_R10_go_ready_packet_contains_chair_command
```

Helper sanity tests: `test_helper_enforce_allowed_write_paths_basic`, `test_target_validation_rejects_max_rounds_nonzero` — both PASS. Total: **12 passed / 0 failed / 0 errors** (`python3 -m pytest tests/anu_codex_micro_refinement_loop/test_regression_10.py`).

### 6. GO_READY packet 예시 (실 사용 가능 형식)

```json
{
  "schema": "anu_v3.go_ready_packet.v1",
  "task_id": "task-2662",
  "ready_for": "DISPATCH",
  "codex_verdict": "PASS_WITH_RECOMMENDATIONS",
  "critical_7": false,
  "permission_expansion": false,
  "forbidden_action": false,
  "required_chair_decision": "FINAL_GO_ONLY",
  "chair_command": "APPROVE FINAL_GO task-2662 verdict=PASS_WITH_RECOMMENDATIONS policy=v3_1_codex_micro_refinement_loop_core_pr_only_no_auto_merge",
  "rounds": 2,
  "changed_files": [
    "memory/reports/task-2662.md",
    "memory/tasks/task-2662.md",
    "tests/anu_codex_micro_refinement_loop/test_regression_10.py"
  ],
  "evidence_paths": [
    "memory/events/task-2662.anu-v3-1-codex-micro-refinement-loop-core-result-260525.json",
    "memory/reports/task-2662.md"
  ],
  "generated_at": "2026-05-25T11:55:00Z"
}
```

Source: two-round convergence (R1 FAIL → safe refinement → R2 PASS_WITH_RECOMMENDATIONS) emitted by `run_micro_refinement`. `chair_command` is the verbatim text 회장 copy-pastes to grant final GO (ANCHOR-5).

### 7. HOLD_FOR_CHAIR packet 예시 (8 safety_gates trigger 명시)

```json
{
  "schema": "anu_v3.hold_for_chair_packet.v1",
  "task_id": "task-2662",
  "hold_reason": "FORBIDDEN_WRITE_TARGET",
  "critical_7": false,
  "triggered_gates": ["forbidden_write_target"],
  "decision_items": [
    {
      "gate": "forbidden_write_target",
      "reason": "FORBIDDEN_WRITE_TARGET",
      "offending_paths": ["dispatch.py"]
    }
  ],
  "recommended_next_action": "ASK_CHAIR",
  "rounds": 1,
  "evidence_paths": ["memory/events/task-2662.codex-findings.json"],
  "offending_paths": ["dispatch.py"],
  "generated_at": "2026-05-25T11:55:00Z"
}
```

**Triggered safety gate**: `forbidden_write_target` (Codex proposed editing `dispatch.py`, which is on the forbidden_paths list — module immediately halts the loop without writing anything and emits the HOLD packet).

The same packet shape is emitted for the other 7 gates (`critical_7`, `security_high_or_critical`, `permission_expansion`, `github_write_required`, `dev_bot_reactivation_required`, `real_write_required`, `scope_expansion`) — regression suite covers each via R3-R8.

### 8. forbidden_action_count

`0`. Zero of the 14 banned actions occurred. No dev bot dispatch, no automatic GitHub write, no merge, no auto-merge, no production mutation, no real write mode, no OWNER PAT manipulation, no credential change, no Axis 1/2/3 runtime edit, no `live settings.json` change, no `dispatch.py` change, no HARNESS_ENFORCED declaration, no ANU-Work production deployment declaration. Branch creation + push + PR open are the only GitHub actions, all explicit per task md 허용 9.

### 9. auto-merge

`0`. No `auto-merge` label on the PR. `gh pr merge` will be invoked **only** on 회장 verbatim FINAL_GO command.

## frozen anchors check

| anchor | enforced by | status |
|--------|-------------|--------|
| ANCHOR-1 Phase 1 Core only | scope of changed_files | OK |
| ANCHOR-2 8 safety_gates → immediate HOLD | `run_micro_refinement` early-return | OK (R3-R8) |
| ANCHOR-3 hard cap 0 | `validate_target` rejects nonzero max_rounds | OK (R9 + helper test) |
| ANCHOR-4 allowed_write_paths enforced | `enforce_allowed_write_paths` | OK (R8 + helper) |
| ANCHOR-5 chair_command in GO_READY | `_build_go_ready_packet` raises if empty | OK (R10) |
| ANCHOR-6 Axis/dispatch/settings/hooks untouched | git diff vs forbidden_paths | OK (diff is purely additive within allowed_write_paths) |
| ANCHOR-7 no HARNESS_ENFORCED / ANU-Work declaration | text search of diff | OK |
| ANCHOR-8 BOT token absence ⇒ HOLD | (deferred — push path uses caller-side credential, this PR only declares logic) | N/A this turn |

## 머지 판단

- **머지 필요**: No (Phase 1 PR-ready only — 회장 FINAL_GO 대기)
- **브랜치**: `task/task-2662-dev2`
- **워크트리 경로**: `/home/jay/workspace/.worktrees/task-2662-dev2`
- **머지 의견**: 12/12 regression PASS, scope inside allowed_write_paths, forbidden_action_count=0, auto-merge label not applied. Awaiting 회장 verbatim `APPROVE FINAL_GO task-2662 …` command per GO_READY packet.

## 발견 이슈 및 해결

1. **pytest import resolution to canonical workspace utils** — `tests/conftest.py` injects `WORKSPACE_ROOT` (defaults to `/home/jay/workspace`) at the front of `sys.path`, so `from utils.anu_codex_micro_refinement_loop import …` resolved to the canonical workspace's `utils/` (which lacks the new modules).
   **Fix**: `tests/anu_codex_micro_refinement_loop/conftest.py` pins `WORKSPACE_ROOT` to the worktree root before any utils import and evicts any pre-cached `utils` module bound to a non-worktree path. Outcome: all 12 regression tests green.

2. **Spec section 5.5 example vs task md 필수 구현 5 — safety_gates key naming** — the spec example used short forms (`github_write`, `dev_bot_reactivation`, `real_write`); task md 단일소스 mandates long forms (`github_write_required`, `dev_bot_reactivation_required`, `real_write_required`).
   **Fix**: long forms adopted across module, schema (`anu_v3_1_micro_refinement_target.json`), and tests — task md verbatim wins per 단일소스 rule.

3. **start_task_guard 강제 worktree 경로 (`.worktrees/task-{id}-{bot}`)** — first attempt created worktree under `/home/jay/.cokacdir/workspace/E9A8FBD2/wt-2662-dev2`; guard rejected, blocking commit.
   **Fix**: relocate to the canonical `/home/jay/workspace/.worktrees/task-2662-dev2`; guard검증 #1 통과.

## 모델 사용 기록

- 팀장(오딘, Opus 4.7) 직접 코딩. 본 작업은 Phase 1 Core 신규 모듈 + 정밀 spec 매핑 작업이라 위임 분해 비용보다 단일 세션 일관성이 더 가치 있다고 판단. 코드 분량 작고 (≈600 LOC 전체) Sonnet 위임 시 spec verbatim 매핑 누락 risk 증가.

## 다음 단계

회장 FINAL_GO 명령 (GO_READY packet의 `chair_command`) 수신 시:

1. PR review acceptance
2. 본 모듈을 v3.1 Phase 2 (ANU-Codex live wiring) 의 dependency 로 활용
3. dispatch.py / hooks 등 forbidden_paths 통합은 별도 task로 회장 승인 후 진행

본 task 결과: **`ANU_V3_1_CODEX_MICRO_REFINEMENT_LOOP_CORE_PR_READY`**
