# Plan 25.2-01 Task 1 Audit — Wrapper Call-Site Enumeration

**Captured:** 2026-05-22 execution start
**Scope:** Inline deliverable per CONTEXT D-03. No code edits in Task 1.

## Cargo.toml pre-flight (RESEARCH Q4 RESOLVED)

`filetime` is NOT present in `[dependencies]` or `[dev-dependencies]` of
`Cargo.toml`. Verified by `grep -n "filetime" Cargo.toml` (exit code 1).

Dev-deps present: `assert_cmd`, `snapbox`, `predicates`, `tempfile`, `rusqlite`.

Task 5 (tests) MUST use the raw `std::fs::File::set_modified` workaround
(stable Rust 1.75+). Do NOT add `filetime` per CLAUDE.md zero-external-runtime
posture.

## #4 Wrapper-side call-site enumeration

Verified via:
`grep -nE "ready_file\(|perch_dir\(|info_file\(|inbox_dir\(" src/live/wrapper/*.rs`

Returns 13 sites — matches RESEARCH §"#4 Call-Site Enumeration" exactly.

| File:Line | Current call | Identity | Classification | Replacement form |
|-----------|--------------|----------|----------------|------------------|
| mod.rs:629 | `owlery::ready_file(&self.psyche_id).exists()` | psyche | NEEDS NESTED SWAP | Form A: `owlery::ready_file_at(&owlery::nested_perch_dir(&self.self_id, &self.psyche_id)).exists()` |
| mod.rs:700 | `owlery::ready_file(&self.psyche_id).exists()` | psyche | NEEDS NESTED SWAP | Form A |
| mod.rs:859 | `owlery::ready_file(&self.psyche_id).exists()` | psyche | NEEDS NESTED SWAP | Form A |
| mod.rs:1100 | `owlery::perch_dir(&self.psyche_id).join("wrapper-state.json")` (WRITER) | psyche wrapper-state | KEEP INLINE FLAT per Q2 RESOLVED | Inline-flat preserved + migration-window comment block |
| lifecycle.rs:23 | `owlery::perch_dir(&psyche_id).join("wrapper-state.json")` (READER) | psyche wrapper-state | NEEDS RESOLVER (Form B reader) | `wrapper_state::wrapper_state_path_resolved(self_id, &psyche_id)` |
| lifecycle.rs:69 | `wrapper_state::write_wrapper_state(&psyche_id, &published)` (WRITER) | psyche wrapper-state | KEEP FLAT per Q2 RESOLVED | Unchanged + migration-window comment block |
| lifecycle.rs:92 | `owlery::perch_dir(&self.psyche_id)` | psyche perch dir | NEEDS NESTED SWAP | Form C: `owlery::nested_perch_dir(&self.self_id, &self.psyche_id)` |
| echo_fire.rs:111 | `owlery::perch_dir(&self.psyche_id).join(".more-done")` | psyche sentinel | NEEDS NESTED SWAP | Form A variant: `owlery::nested_perch_dir(&self.self_id, &self.psyche_id).join(".more-done")` |
| echo_fire.rs:152 | `owlery::info_file(&self.self_id)` | **Self** | LEAVE FLAT per Phase 25 D-01 ("Self perch IS the parent") | unchanged |
| orphan.rs:59 | `owlery::info_file(self_id)` | **Self** | LEAVE FLAT per Phase 25 D-01 | unchanged |
| orphan.rs:142 | `owlery::perch_dir(&self.self_id)` | **Self** | LEAVE FLAT per Phase 25 D-01 | unchanged |
| orphan.rs:242 | `owlery::ready_file(&self.psyche_id)` | psyche | NEEDS NESTED SWAP | Form A — `self.self_id` + `self.psyche_id` are both in scope on `WrapperState` |
| orphan.rs:309 | `crate::common::owlery::perch_dir(id)` (TEST helper `write_test_info_json`) | test fixture | TEST-ONLY — leave as-is | unchanged |
| orphan.rs:321 | `crate::common::owlery::info_file(id)` (TEST helper) | test fixture | TEST-ONLY — leave as-is | unchanged |

**Totals:** 8 production psyche-side sites need nested swap; 3 Self-side sites
stay flat (Phase 25 D-01); 2 test-only sites left as-is (planner discretion).
Matches the "8 production + 3 Self + 2 test = 13" count in RESEARCH.

Additionally, `claude.rs:155-178` post-`init_session` `write_wrapper_state(&self.psyche_id, &state)`
is a WRITER that KEEPS FLAT per Q2 RESOLVED + migration-window comment block.

## D-06 read_wrapper_state consumer enumeration

Verified via `grep -rn "read_wrapper_state\b" src/`.

Production bare-call sites (the D-06 consumer set):
1. `src/live/start.rs:597` — `emit_boot_trigger_after_spawn` (boot trigger)
2. `src/live/signoff.rs:197` — `emit_signoff_trigger` (signoff trigger)

All other matches are either:
- The helper definition itself at `src/common/wrapper_state.rs:155`
- Doc-comment references (signoff.rs:192, 268; start.rs:544, 574; wrapper/claude.rs:350; wrapper/lifecycle.rs:59; wrapper/mod.rs:570)
- Module-local test bodies in `src/common/wrapper_state.rs:241/261/269/285/301`
- Code comment at `src/owl/echo_commune.rs:934` (NOT a bare call — verified by re-read)

**Task 4 converts BOTH production sites + adds the grep gate.** No commune/pulse/init
consumers exist today; future readers are forced into the helper by signature
divergence (helper takes `(self_id, psyche_id, site)`; opt-out `read_wrapper_state(agent_id)`
remains for tests).

## Form B treatment split (Q2 RESOLVED)

- **Reader at lifecycle.rs:23** → routes through `wrapper_state_path_resolved`
  (nested-first, flat-fallback). `load_and_delete(&path)` is `&Path`-keyed
  so passing a PathBuf from the resolver does NOT require an API surface change.
- **Writer at mod.rs:1100** → KEEPS inline flat `owlery::perch_dir(&self.psyche_id).join(...)`
  with a migration-window comment block citing Q2 RESOLVED + RESEARCH
  §"Why reader-side, not writer-side".
- **Writers via convenience helper** (`claude.rs:155-178`, `lifecycle.rs:69`) →
  KEEP `write_wrapper_state(&psyche_id, &state)` which resolves through the
  flat `wrapper_state_path(agent_id)`. Migration-window comment block applied.
