diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fb8ff03 --- /dev/null +++ b/.gitignore @@ -0,0 +1,52 @@ +# Node +node_modules/ +build/ +dist/ + +# Private keys (CRITICAL — never commit) +*.pem +*.key +*-key.txt +private-key* +keys* +*keypair* +*.jwk +*.hex +!package-lock.json + +# macOS +.DS_Store +.AppleDouble + +# IDE / agent tooling (hook configs auto-execute code — never commit) +.vscode/ +.cursor/ +.claude/ +.impeccable/ + +# Environment / secrets +.env +.env.local + +# Python +__pycache__/ +*.pyc +.venv/ +venv/ + +# Next.js +.next/ +out/ + +# Kagi thread exports — private AI conversations. Run extract_kagi_conversations.sh +# OUTSIDE this repo (e.g. ~/dev/_shared-local/ or /tmp), never in the tree. +kagi-conversations-*/ + +# Chat sync artifacts — local-only (red-team SEC-07) +**/agent_logging/ + +# Audit output — never commit red-team ledgers (AGENTS.zodiac.md rule) +red-team-output/ + +# OneDrive artifacts +~* diff --git a/docs/STUDIO-MIGRATION-STATUS.md b/docs/STUDIO-MIGRATION-STATUS.md deleted file mode 100644 index 37d5fa3..0000000 --- a/docs/STUDIO-MIGRATION-STATUS.md +++ /dev/null @@ -1,77 +0,0 @@ -# Studio Migration — COMPLETE (final status + post-migration TODO) -**Last updated:** 2026-08-11 ~22:15 EDT (end of night 2) -**State: MIGRATION DONE. §1–§9 all executed. Air stats deleted after -OneDrive cloud-side spot-check passed. Only cosmetic TODOs remain.** - -## Final architecture -| | Mac Studio (always-on host) | MacBook Air ("ole Blu") | -|---|---|---| -| 02:00 daily | com.psingletary.backup-bundles → 6 repo bundles → OneDrive repo-bundles/ | com.psingletary.backup-journal → Interactive_Journal.bundle → same | -| 12:00 daily | com.lottery.playslips (runs ~/dev/stats/daily_run.sh; syncs OneDrive stats-backup/) | — | -| Sun 11:00 | com.user.sched-cleanup | com.user.sched-cleanup (kept by design) | -| On sync | — | com.psingletary.studio-watcher (WatchPaths on _status_studio.log → banner) | -| Owns exclusively | ~/dev/stats (NOT a git repo; OneDrive stats-backup/ is its vault) | ~/dev/Interactive_Journal (NEVER goes to the Studio) | - -- All repos on Tangled, DID-form remotes only (handle-form fails knot lookup). -- OneDrive = cold-storage vault; git/Tangled = sync. GitHub retired. -- Studio Mullvad config: never touched. ssh studio = LAN-only key auth. -- Cleanup kit's git repo lives at OneDrive env/cleanup/ (not ~/dev); - installer deploys clean.sh → ~/.scripts/, label com.user.sched-cleanup. - -## DID table -| repo | did | -|---|---| -| _shared | did:plc:gbmu2edwp7u7dva6x62gpgre | -| altifier | did:plc:h46uvw3x22m5utvqgfjb2ax5 | -| ATProtocol-Playground | did:plc:vk25i3scormvs6kijn3sqzi7 | -| ptharbor | did:plc:3agqazx4qurp26ksohwavygt | -| verifier | did:plc:hkla7ikm6duiuvtmtd7aa6tr | -| zodiac | did:plc:mo67zhweppd37oncmu3p5yji | -| cleanup (OneDrive env/cleanup) | did:plc:2hzdu4lpcy6l25o5g3js5gda | -| account | did:plc:stznz7qsokto2345qtdzogjb | - -## Post-migration TODO (all cosmetic, none urgent) -- [ ] Pin (Studio): Finder → OneDrive repo-bundles/ → "Always Keep on - This Device" (launchd context can't materialize dataless stubs) -- [ ] Pin (Air): same for _status_studio.log (watcher reliability) -- [ ] Free up (Air): Finder → repo-bundles/ → "Free Up Space" - (xattr route was a no-op; re-downloads on next 2 AM write are fine) -- [ ] ptharbor: default branch → master in Tangled web UI -- [ ] daily_run.sh: "4/3 games" counter bug (Studio, ~/dev/stats/) -- [ ] cleanup kit install.sh line 166: DAY_NAMES[$WEEKDAY] — zsh arrays are - 1-indexed, Sunday=0 misses the pretty-print. Schedule itself correct. - Fix in OneDrive env/cleanup repo + push. -- [ ] Morning-after check (2026-08-12): watcher banner from the 2 AM - runs = whole pipeline self-verified overnight -- [ ] Sunday check (2026-08-16): both machines ran sched-cleanup at 11:00 - -## Resume prompt (copy the indented block below into a new chat) - - I'm resuming post-migration cleanup on my two-Mac setup. Context: - - - MacBook Air "ole Blu" (my daily driver, where I run commands) and an - always-on Mac Studio, reachable via `ssh studio` (LAN-only, key auth). - - Migration is COMPLETE. Full state, architecture, DID table, and the - open TODO list live in ~/dev/_shared/docs/STUDIO-MIGRATION-STATUS.md - (git repo, also on Tangled). Read that file first — I'll paste it if - you ask. - - Hard rules: never touch the Studio's Mullvad config; Interactive_Journal - repo never leaves the Air; git remotes must use DID-form Tangled URLs - (git@tangled.org:did:plc:...) — handle-form fails; ~/dev/stats lives - ONLY on the Studio and is NOT a git repo (OneDrive stats-backup/ is - its backup); OneDrive files can be dataless stubs in launchd context. - - Workflow we use: you give me one zsh paste at a time for ole Blu (with - ssh studio '...' for remote bits), tell me what output to expect, I - paste results back, you interpret before the next step. - - Today I want to work through the "Post-migration TODO" checklist in the - status doc. Start by asking me to paste the current TODO section, then - take the items in whatever order is most sensible. - -## History -Night-2 fixes for the record: daily_run.sh (a) ${SUMMARY:-} unbound-var -crash under set -u, (b) missing OneDrive stats-backup/ target, (c) PATH -prepend /opt/homebrew/bin for python 3.14 (Counter.total() needs >=3.10). -Lock file: ~/dev/stats/logs/.last_run_date (delete for same-day rerun). -Plan doc (mac_studio_setup_plan.md, this dir) is historical — see its -addendum banner for corrections (§3 URLs, §5f reality, launchd lessons). diff --git a/docs/mac_studio_setup_plan.md b/docs/mac_studio_setup_plan.md deleted file mode 100644 index e5df390..0000000 --- a/docs/mac_studio_setup_plan.md +++ /dev/null @@ -1,170 +0,0 @@ -> **⚠️ ADDENDUM — 2026-08-11 (migration executed, functionally complete)** -> This plan was executed over two nights. It is now a historical document; -> the live source of truth is `STUDIO-MIGRATION-STATUS.md` in this directory. -> Corrections discovered during execution: -> - **§3 clone URLs:** handle-form (`psingletary.com/...`) failed knot lookup -> for some repos. Use canonical DID-form only: -> `git@tangled.org:did:plc:/` — full DID table is in the -> status doc. -> - **§5f cleanup repo:** never lived in `~/dev` and isn't cloned from -> Tangled. The git repo lives at OneDrive `env/cleanup/`; its installer -> deploys `clean.sh` → `~/.scripts/` with label `com.user.sched-cleanup` -> (not `com.psingletary.*`). Studio install was done from the synced kit. -> - **§5 general:** launchd jobs on the Studio needed `/opt/homebrew/bin` -> prepended to PATH, and OneDrive files are dataless stubs in launchd -> context (materialize or pin before relying on them). - -# Mac Studio Setup Plan (v2 — LAN-only, Studio as automation host) -**Goal:** identical ~/dev layout on both machines; git/Tangled as sync, -OneDrive as vault; Studio = always-on automation host; Mullvad untouched. - -## Machine roles -| | Mac Studio (mac-studio-2022.local) | MacBook Air | -|---|---|---| -| Role | Primary dev + automation host | Portable dev | -| Scheduled jobs | 2 AM bundles, noon lottery, Sun 11 AM cleanup | Journal bundle, status watcher, Sun 11 AM cleanup | -| Interactive_Journal | NOT present — never clone it here | Sole copy, sole writer | -| ~/dev/stats | Sole copy (whole tree, not a repo) | None — reads outputs from OneDrive | -| VPN | Mullvad, split-tunneled (DO NOT TOUCH) | — | -| Remote Login (SSH) | Enabled, keep enabled | — | - -## Network topology (verified 2026-08-10) -- Both machines share the honeypot Wi-Fi subnet 192.168.86.x — this is the - SSH path (Mullvad local-network sharing works same-subnet only) -- Studio: Wi-Fi 192.168.86.218, Ethernet 192.168.1.220 on the main LAN - (the Air canNOT reach 192.168.1.x directly — do not use those IPs) -- Air uses SSH alias `ssh studio` (HostName mac-studio-2022.local, key auth) -- TODO: DHCP reservation for the Studio Wi-Fi MAC in the honeypot router - -## 0. Prerequisites (Studio) -- [x] Mullvad "Local network sharing" enabled (verified 2026-08-10) -- [ ] System Settings > General > Sharing > Remote Login: ON (keep on) -- [ ] System Settings > Energy: "Prevent automatic sleeping when the - display is off" ON; "Start up automatically after a power failure" ON -- [ ] Sign into iCloud + OneDrive; let OneDrive fully sync -- [ ] Xcode CLT (`xcode-select --install`), Homebrew, git -- [ ] brew install python terminal-notifier - (stats is stdlib-only — no pip packages needed; verified 2026-08-10) -- NEVER place working repos under ~/Library/CloudStorage/ - -## 1. Hermes bootstrap (run from the AIR) -Hermes on the Air connects over LAN SSH, installs Hermes on the Studio; -the Studio's Hermes then executes sections 2-8 locally. - - ssh studio # verify connectivity first - # then install Hermes on the Studio per its install method and hand - # it this document from ~/dev/_shared/docs/ - -## 2. SSH + Tangled (Studio) - - ssh-keygen -t ed25519 -C "psingletary-studio" - cat ~/.ssh/id_ed25519.pub - -Add as a NEW key on Tangled (never copy the Air's private key). - -## 3. Clone the code repos (Studio) — _shared first - - mkdir -p ~/dev && cd ~/dev - git clone git@tangled.org:did:plc:gbmu2edwp7u7dva6x62gpgre _shared - git clone git@tangled.org:psingletary.com/altifier altifier - git clone git@tangled.org:psingletary.com/ATProtocol-Playground ATProtocol-Playground - git clone git@tangled.org:did:plc:3agqazx4qurp26ksohwavygt ptharbor - git clone git@tangled.org:psingletary.com/verifier verifier - git clone git@tangled.org:did:plc:mo67zhweppd37oncmu3p5yji zodiac - -Do NOT clone Interactive_Journal. It lives on the Air only. -AIR follow-up (GitHub migration cleanup): repoint the old remote — - - git -C ~/dev/ATProtocol-Playground remote set-url origin git@tangled.org:psingletary.com/ATProtocol-Playground - -## 4. Move stats to the Studio (whole tree — it is not a repo) - - # on the STUDIO (Air must have Remote Login ON temporarily, - # or push from the Air with the paths reversed): - rsync -avh --progress patricksingletary@AIR_IP:dev/stats/ ~/dev/stats/ - mkdir -p ~/dev/stats/logs - -Verify counts match on both ends: find ~/dev/stats -type f | wc -l -Script outputs must land in OneDrive (stats-backup/ or equivalent) — that -is where the Air reads results. Delete the Air's copy ONLY at section 9. - -## 5. launchd migration -### 5a. Commit plists to the repo FIRST (on the Air) - - mkdir -p ~/dev/_shared/launchd - cp ~/Library/LaunchAgents/com.psingletary.backup-bundles.plist ~/dev/_shared/launchd/ - cp ~/Library/LaunchAgents/com.lottery.playslips.plist ~/dev/_shared/launchd/ - # plus install.sh that cp's to ~/Library/LaunchAgents and bootstraps - git -C ~/dev/_shared add launchd - git -C ~/dev/_shared commit -m "launchd: add plists + installer" - git -C ~/dev/_shared push - -Both plists verified portable 2026-08-10: absolute /Users/patricksingletary -paths + runtime ~ expansion; same username on both machines; no edits needed. - -### 5b. Install on the Studio (after _shared clone) - - cp ~/dev/_shared/launchd/*.plist ~/Library/LaunchAgents/ - launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.psingletary.backup-bundles.plist - launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.lottery.playslips.plist - -Remove Interactive_Journal from the Studio bundle script's repo list. - -### 5c. Status-line hook (Studio) — powers the Air notification -Append to the end of each job script: - - echo "$(date '+%F %T') studio $JOB_NAME OK" >> ~/Library/CloudStorage/OneDrive-Personal/repo-bundles/_status_studio.log - -### 5d. Journal bundle job (stays on the AIR) -New minimal plist com.psingletary.backup-journal (2 AM): bundles ONLY -~/dev/Interactive_Journal to OneDrive repo-bundles/. Commit to _shared/launchd. - -### 5e. Notification watcher (AIR) -launchd agent, WatchPaths on the _status_studio.log path; on change run: -osascript -e 'display notification "Studio jobs ran" with title "Automation"' -Finder: mark _status_studio.log "Always Keep on This Device" on the Air. - -### 5f. Weekly cleanup — DUPLICATE onto the Studio (keep on the Air too) -It has its own repo + installer: - - cd ~/dev - git clone git@tangled.org:psingletary.com/macOS-sched-cleanup.git - cd macOS-sched-cleanup && ./install.sh # Sunday 11 AM default - -Requires terminal-notifier (section 0). Modules self-skip if their -target software is absent. Do NOT unload this job on the Air. - -## 6. Full Disk Access (Studio — before the first 2 AM run) -System Settings > Privacy & Security > Full Disk Access. -`open /bin`, DRAG zsh onto the FDA list and toggle on. Grant bash too -(the lottery job runs under /bin/bash). - -## 7. Verification gates (Studio) — run WHILE Mullvad is connected - - # repos healthy - for d in ~/dev/*/.git(N:h); do echo "== $d"; git -C $d fsck --no-progress; git -C $d status -sb; done - # bundle job from launchd context - : > /tmp/backup-bundles.log - launchctl kickstart gui/$(id -u)/com.psingletary.backup-bundles - sleep 10; cat /tmp/backup-bundles.log - -Gates: all OK lines, no "Operation not permitted", bundles visible in -OneDrive, status line written, Air notification fires. - -## 8. Air decommission (ONLY after 2 consecutive successful Studio runs) - - launchctl bootout gui/$(id -u)/com.psingletary.backup-bundles - launchctl bootout gui/$(id -u)/com.lottery.playslips - mkdir -p ~/dev/_shared/launchd/retired-air - mv ~/Library/LaunchAgents/com.lottery.playslips.plist ~/dev/_shared/launchd/retired-air/ - rm -rf ~/dev/stats # Studio copy + OneDrive outputs verified first! - -Do NOT bootout com.user.sched-cleanup — it runs on BOTH machines. -Keep on the Air: journal bundle (5d), status watcher (5e), sched-cleanup. -Storage reclaim: OneDrive Files On-Demand; free up repo-bundles/ locally. - -## 9. Git hygiene (both machines) -- Commit + push at end of every session; pull before starting -- Remotes are the sync mechanism — never rsync working trees (exception: - the one-time stats move in section 4) -- git config --global pull.rebase true (on both) diff --git a/docs/notes_from_cleanup.md b/docs/notes_from_cleanup.md deleted file mode 100644 index 1a1cd3c..0000000 --- a/docs/notes_from_cleanup.md +++ /dev/null @@ -1,66 +0,0 @@ -# Notes from the OneDrive → ~/dev Migration Cleanup -**Date:** 2026-08-10 · **Machine:** MacBook Air · **Status:** COMPLETE 🔔 - -## What happened -Git repos previously lived in `~/Library/CloudStorage/OneDrive-Personal/hermes/`. -macOS File Provider mediation caused git I/O timeouts and corruption risk -(e.g. hangs writing `COMMIT_EDITMSG`). Everything was migrated to local APFS -at `~/dev/`, with OneDrive demoted to a cold-storage vault. - -## Final architecture -| Layer | Location | Contents | -|---|---|---| -| Working trees | `~/dev/` (local APFS) | 7 git repos + stats project | -| Hot/offsite sync | Tangled remotes | 6 code repos (NOT Interactive_Journal) | -| Cold backup | OneDrive `repo-bundles/` | nightly `git bundle --all` per repo, evicted locally | -| Stats data backup | OneDrive `stats-backup/` | one-shot rsync from the noon lottery job | - -## Inventory of ~/dev -- `_shared/` — scripts (backup-bundles.zsh), templates, docs, plan.md -- `altifier/`, `ATProtocol-Playground/`, `ptharbor/`, `verifier/`, `zodiac/` — code repos, Tangled remotes -- `Interactive_Journal/` — **local-only git repo, deliberately NO remote** - (personal content: career, divorce, finances, children). Backed up ONLY via - nightly bundles to OneDrive. Never push this to any git host. -- `stats/` — lottery playslips project (not yet a git repo; see TODO) - -## Automation -| Job | Label | Schedule | Notes | -|---|---|---|---| -| Bundle backups | `com.psingletary.backup-bundles` | 2:00 AM nightly | zsh; needs FDA for `/bin/zsh` (granted 2026-08-10) | -| Lottery playslips | `com.lottery.playslips` | 12:00 PM daily | bash; runs `~/dev/stats/scripts/daily_run.sh`; retargeted from old `~/stats` | - -## Near-misses & lessons learned -1. **Blind delete almost lost data.** `hermes/` contained two folders outside the - six known repos: `Interactive_Journal` and `stats`. Always `ls` before `rm`. -2. **A hidden writer existed.** `com.lottery.playslips` was rsync-backing into - `hermes/stats` daily. Found via `grep -il hermes ~/Library/LaunchAgents/*.plist`. -3. **Three copies of stats existed** (`~/stats` live, OneDrive backup, `~/dev/stats` - stale) and **neither was a superset** — resolved with a union merge - (`rsync -a -b --suffix=".from-dev"`), live side winning. -4. **launchd ≠ your shell.** The bundle job worked interactively but failed from - launchd until `/bin/zsh` got Full Disk Access (TCC blocks CloudStorage paths). -5. **Finder AppleScript delete quirks:** error -1728 fixed with `as alias` - coercion; error -8013 ("needs to be downloaded") happens on evicted/dataless - placeholders — Finder can't Trash them. `rm -rf` works and OneDrive's web - recycle bin (~30 days) is the safety net. -6. **⌘⇧G doesn't work in the FDA file picker** — use `open /bin` + drag `zsh` - onto the FDA list instead. -7. **Bundle scripts iterating `*/.git` silently skip non-repos.** IJ and stats - were invisible to backups until IJ was `git init`-ed. - -## Known bugs / debt -- `daily_run.sh` references undefined `$SUMMARY` at the end (should be - `$SUMMARY_FULL`) — harmless "unbound variable" error after real work completes. -- 13 `.from-dev` conflict files in `~/dev/stats` awaiting review (mostly - `output/latest` and old logs). -- `~/stats.old` retained as insurance; delete after ~1 week of clean noon runs. - -## TODO -- [ ] 2026-08-11: verify 2 AM bundle run (fresh timestamps in repo-bundles/) -- [ ] 2026-08-11: verify noon run wrote `~/dev/stats/output/runs/2026-08-11/` and created `stats-backup/` in OneDrive -- [ ] Review/delete `.from-dev` files: `find ~/dev/stats -name "*.from-dev"` -- [ ] ~2026-08-17: `rm -rf ~/stats.old` -- [ ] `git init ~/dev/stats` — gitignore `data/`, `output/`, `logs/`; Tangled remote for code only -- [ ] Auto-commit patch in backup-bundles.zsh (`.autocommit` marker) so journal edits get bundled without manual commits -- [ ] Write `gen-agents.zsh` (AGENTS.common.md → per-project AGENTS.md generator) -- [ ] Fix `$SUMMARY` bug in daily_run.sh diff --git a/launchd/com.lottery.playslips.plist b/launchd/com.lottery.playslips.plist deleted file mode 100644 index 91af2f9..0000000 --- a/launchd/com.lottery.playslips.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - Label - com.lottery.playslips - - ProgramArguments - - /bin/bash - /Users/patricksingletary/dev/stats/scripts/daily_run.sh - - - WorkingDirectory - /Users/patricksingletary/dev/stats - - EnvironmentVariables - - PATH - /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin - HOME - /Users/patricksingletary - - - StartCalendarInterval - - Hour - 12 - Minute - 0 - - - StandardOutPath - /Users/patricksingletary/dev/stats/logs/launchd_stdout.log - - StandardErrorPath - /Users/patricksingletary/dev/stats/logs/launchd_stderr.log - - RunAtLoad - - - KeepAlive - - - LowPriorityIO - - - diff --git a/launchd/com.psingletary.backup-bundles.plist b/launchd/com.psingletary.backup-bundles.plist deleted file mode 100644 index 564b418..0000000 --- a/launchd/com.psingletary.backup-bundles.plist +++ /dev/null @@ -1,17 +0,0 @@ - - - - - Labelcom.psingletary.backup-bundles - ProgramArguments - - /bin/zsh - -c - ~/dev/_shared/bin/backup-bundles.zsh - - StartCalendarInterval - Hour2Minute0 - StandardOutPath/tmp/backup-bundles.log - StandardErrorPath/tmp/backup-bundles.log - - diff --git a/launchd/com.psingletary.backup-journal.plist b/launchd/com.psingletary.backup-journal.plist deleted file mode 100644 index 77b3744..0000000 --- a/launchd/com.psingletary.backup-journal.plist +++ /dev/null @@ -1,17 +0,0 @@ - - - - - Labelcom.psingletary.backup-journal - ProgramArguments - - /bin/zsh - /Users/patricksingletary/dev/_shared/bin/backup-journal.zsh - - StartCalendarInterval - Hour2Minute0 - RunAtLoad - StandardOutPath/tmp/backup-journal.log - StandardErrorPath/tmp/backup-journal.log - - diff --git a/launchd/com.psingletary.backup3.plist b/launchd/com.psingletary.backup3.plist deleted file mode 100644 index 0920b6c..0000000 --- a/launchd/com.psingletary.backup3.plist +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Labelcom.psingletary.backup3 - ProgramArguments - - /bin/zsh - /Users/patricksingletary/dev/_shared/bin/backup3.zsh - --apply - - - StartInterval60 - RunAtLoad - StandardOutPath/tmp/backup3.log - StandardErrorPath/tmp/backup3.log - - diff --git a/launchd/com.psingletary.studio-watcher.plist b/launchd/com.psingletary.studio-watcher.plist deleted file mode 100644 index 72560d0..0000000 --- a/launchd/com.psingletary.studio-watcher.plist +++ /dev/null @@ -1,19 +0,0 @@ - - - - - Labelcom.psingletary.studio-watcher - ProgramArguments - - /bin/zsh - /Users/patricksingletary/dev/_shared/bin/studio-watcher.zsh - - WatchPaths - - /Users/patricksingletary/Library/CloudStorage/OneDrive-Personal/repo-bundles/_status_studio.log - - RunAtLoad - StandardOutPath/tmp/studio-watcher.log - StandardErrorPath/tmp/studio-watcher.log - -