---
quick_id: 260416-4y2
type: execute
mode: quick
wave: 1
completed: 2026-04-16
duration_seconds: 177
files_modified:
  - src/live/wrapper/claude.rs
  - psyche.md
binary_rebuilt: target/release/owl.exe
commits:
  - hash: 4db1be9
    message: "fix(wrapper): anchor psyche subprocess cwd to tracked dir"
  - hash: f088b0e
    message: "fix(psyche): correct context file path to canonical tracked dir"
---

# Quick Task 260416-4y2: Fix Psyche Permission on Context/Memform Summary

Anchored all four `claude -p` subprocess spawn sites in the Psyche wrapper to `owlery::psyche_dir()` and updated the embedded `psyche.md` to use relative filenames (`{{self_id}}.md`). Psyche can now Read/Write/Edit its canonical context file under `~/.claude/spacetime/psyches/tracked/` without hitting Claude Code workspace-permission errors.

## What Was Built

### Task 1: Anchor claude subprocess cwd to psyche tracked dir (commit `4db1be9`)

**File:** `src/live/wrapper/claude.rs`

Added `use crate::common::owlery;` at line 7. Inserted `.current_dir(owlery::psyche_dir())` on the `Command` builder at every spawn site — immediately after `Command::new(&self.cli_binary)` and before any other configuration:

| Spawn Site | Line (after edit) | Method |
|------------|-------------------|--------|
| `init_session` | 39 | `init_cmd.current_dir(owlery::psyche_dir());` |
| `resume_session` (dead_code backcompat) | 153 | `resume_cmd.current_dir(owlery::psyche_dir());` |
| `resume_session_checked` | 237 | `resume_cmd.current_dir(owlery::psyche_dir());` |
| `final_session` | 345 | `final_cmd.current_dir(owlery::psyche_dir());` |

The two recovery paths in `handle_pulse_trigger_recovery` (tier 1 and tier 2) inherit the fix automatically because they call `init_session()` and `resume_session_checked()`. No other changes: arg lists, `env_remove`, stdio piping, CREATE_NO_WINDOW flags, and log calls remain identical.

Net diff: `+5 insertions, 0 deletions`.

### Task 2: Correct context file path in psyche.md (commit `f088b0e`)

**File:** `psyche.md`

Replaced four occurrences of `~/.claude/owlery/{{self_id}}/psyche-context.md` with the relative filename `{{self_id}}.md`:

| Line | Section | Context |
|------|---------|---------|
| 81 | `<first_invocation>` Step 1 | Read prior context |
| 85 | `<first_invocation>` Step 2 | Write initial snapshot |
| 199 | `<init_signoff>` | Write accumulated context on shutdown |
| 225 | `<context_save>` | Periodic batch save every 3-5 COMMUNEs |

The relative path resolves against the subprocess cwd (set by Task 1 to `owlery::psyche_dir()`), producing `~/.claude/spacetime/psyches/tracked/{self_id}.md` — matching the convention already used by `src/live/context.rs::run_save` and `run_download`.

No other lines in `psyche.md` were modified.

Net diff: `+4 insertions, -4 deletions`.

### Task 3: Build, test, and confirm embedded psyche.md

Ran `cargo build --release`, then the test suite. Binary rebuilt at 2026-04-16 03:39 (mtime).

## Verification Results

### Build
- `cargo build --release` — **PASS** (5.13s Task 1 check, 5.09s Task 3 final). Only 3 pre-existing warnings for unused fields/functions unrelated to this plan (`source`, `remove_pulse_by_message`, `remove_pulse`).

### Tests
- `cargo test --release --lib` — **PASS** (21/21 library unit tests).
- `cargo test --release` (full suite) — **PASS** (122 tests across all binaries, 0 failed, 0 ignored).

Test totals per binary:
| Binary | Passed |
|--------|--------|
| lib unit tests | 21 |
| integration (group 1) | 43 |
| integration (group 2) | 8 |
| integration (group 3) | 9 |
| integration (group 4) | 7 |
| native_owl | 21 |
| result_variants | 13 |

### Embedded psyche.md sanity
- `grep -c "Read the file at" target/release/owl.exe` → `1` (new string present)
- `grep -c "psyche-context.md" target/release/owl.exe` → `0` (stale string purged)
- `grep -c "owlery/{{self_id}}" target/release/owl.exe` → `0` (stale path purged)

### Source verification
- `grep -c "current_dir(owlery::psyche_dir" src/live/wrapper/claude.rs` → `4` (all four spawn sites anchored)
- `grep -c "use crate::common::owlery;" src/live/wrapper/claude.rs` → `1` (import present)
- `grep -c "owlery/{{self_id}}/psyche-context.md" psyche.md` → `0` (no stale refs)
- `grep -c "{{self_id}}.md" psyche.md` → `4` (new refs at lines 81, 85, 199, 225)

## Deviations from Plan

### Auto-fixed Issues

**1. [Rule 3 - Blocking] Pre-staged unrelated file in initial Task 1 commit**

- **Found during:** Task 1 commit
- **Issue:** The git index had pre-staged modifications to `src/owl/hook_idle.rs` (from an unrelated quick task 260416-uz8 that was being worked in parallel). `git add src/live/wrapper/claude.rs` merged my file into the existing staged set instead of replacing it, so the first commit accidentally included 150+ unrelated lines from `hook_idle.rs`.
- **Fix:** Ran `git reset --mixed HEAD~1` (non-destructive; prohibition is on `--hard`) to undo the commit, then staged only `src/live/wrapper/claude.rs` explicitly and recommitted. The final Task 1 commit (`4db1be9`) contains exactly 5 insertions in one file. Repeated the same explicit unstage pattern for Task 2 (unstaged pre-existing `.planning/` artifacts before committing `psyche.md`).
- **Files modified:** None — purely a commit-hygiene correction.
- **Commit:** `4db1be9` (Task 1), `f088b0e` (Task 2) are both clean

## Authentication Gates

None.

## User Action Required: Deploy

The fix lives in the freshly built `target/release/owl.exe`. **To activate it in the live skill, the user must run the deploy steps in `docs/DEPLOY.md`:**
- Copy `target/release/owl.exe` → `~/.claude/skills/owl/owl.exe`
- Copy `SKILL.md` → `~/.claude/skills/owl/SKILL.md`
- Copy `LIVE-SKILL.md` → `~/.claude/skills/live/SKILL.md`

Until deploy, `~/.claude/skills/owl/owl.exe` still runs the old binary with the broken paths and unanchored subprocess cwds.

## Success Criteria

- [x] Claude subprocesses spawned by the wrapper (init, resume, resume_checked, final) run with cwd = `owlery::psyche_dir()`
- [x] Psyche's embedded prompt instructs it to Read/Write `{{self_id}}.md` (relative)
- [x] File path convention matches `src/live/context.rs::run_save` and `run_download`
- [x] No changes to wrapper state, lifecycle, file path convention, or `--add-dir` flag
- [x] No changes to `src/live/context.rs`
- [x] Binary rebuilt; all library tests pass
- [x] Full test suite passes (122/122)

## Self-Check: PASSED

- FOUND: `src/live/wrapper/claude.rs` — 4 `.current_dir(owlery::psyche_dir())` calls + `use` import
- FOUND: `psyche.md` — 4 `{{self_id}}.md` refs at lines 81, 85, 199, 225; 0 stale refs
- FOUND: `target/release/owl.exe` — rebuilt at 2026-04-16 03:39, contains new psyche.md strings, zero stale strings
- FOUND: commit `4db1be9` (Task 1)
- FOUND: commit `f088b0e` (Task 2)
