# Pi settings single-writer ownership

audience: AI coding agents first.

- Status: DONE — landed, deployed, canonical links and installed remote dispatch proven.
- Outcome: canonical deployed Overdeck path solely owns live Pi-managed paths. Runtime settings changes cross one atomic `deckctl` pull/apply transaction. Foreign provenance and direct unmanaged writes fail closed. Deployment reconciles content hashes + provenance, never mtimes.
- Source request (owner, 2026-08-12): recurring drift has two writers: live Pi/agents edit settings directly while deployment treats repository settings as authoritative. Foreign symlinks prevent safe pull/deploy reconciliation. Repair ownership permanently; preserve and merge legitimate current contents before relinking.

## Acceptance criteria

1. Every manifest-managed live Pi path resolves only into canonical deploy clone.
2. Preserve foreign-target/live contents before replacing links. Merge legitimate settings delta, including deployed `gpt-sol.ts` package.
3. Runtime settings persistence uses one atomic `deckctl` transaction. Direct writes outside transaction are rejected or detected before overwrite.
4. Apply decisions use content hash + symlink provenance; mtime has no authority.
5. Regression proves apply → runtime edit → pull → apply → zero `sync diff` drift.
6. Focused sync tests pass cleanly.
7. Install repaired runtime before landing; prove real installed transaction and remote `local-gate` dispatch.
8. Land all work on `main`, run full `packaging/deploy-local.sh`, then repeat installed proof.
9. `local_fallback` remains `false`.

## Preserved WIP

- Worktree: `/home/user/Projects/overdeck/.worktrees/rb-static-factory`
- Branch: `wt/rb-static-factory`
- Commit `0ec6b5fe2`: legitimate live Pi `gpt-sol.ts` settings entry; MUST preserve.
- Scheduler repair already landed: `8d7542a91`.
- Before any live relink, snapshot bytes and provenance for `~/.pi/agent/settings.json`, `~/.pi/agent/extensions`, `~/.pi/agent/models.json`, and `~/.pi/context-mode`.

## Constraints

- NEVER delegate or offload. Worker `main` owns execution and loud failure handling.
- NEVER mutate shared main checkout.
- NEVER delete/replace foreign live targets before preservation and content comparison.
- Canonical live target: `${OVERDECK_DEPLOY_DIR:-$HOME/.local/share/overdeck/deploy}/modules/workstation/pi/...`.
- Repository remains landed source; deploy clone is sole runtime writer/target.
- Keep unrelated WIP untouched.

## Execution steps

1. Inventory manifest, sync engine, fleet convergence, tests, live paths, canonical targets, content hashes, and provenance.
2. Pin Pi managed entries to deploy source where runtime ownership requires it.
3. Implement preservation-first, provenance-aware, content-hash reconciliation and atomic runtime-change transaction.
4. Add direct-write rejection/detection and round-trip regression.
5. Run focused tests; address every signal.
6. Install into canonical deploy runtime; preserve/merge/relink live Pi paths; prove zero drift.
7. Commit, refresh `origin/main`, integrate current main, direct-land per incident escape hatch, full deploy.
8. Prove installed `local-gate` remote dispatch and update receipts.

## Current receipt

2026-08-12 DONE: landed main `65ff076e8`; deploy clone clean at same commit; full `packaging/deploy-local.sh` returned deployed with collector HTTP 401 (healthy authenticated endpoint). Live `settings.json`, extensions, and models resolve only into canonical deploy; obsolete dangling `context-mode` link removed after hash/provenance inventory. `~/.local/bin/pi` resolves to canonical deploy wrapper. `deckctl sync diff pi` exits 0. Installed `local-gate` remote canary printed `STATIC_REMOTE_OK`. Focused gates: sync 65/65, deploy 30/30, core 15/15. Deployment printed pre-existing non-live checkout shim hazards; live shims match `origin/main`, so deploy correctly classified them non-blocking.

## Next executable action

None.
