diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-11 17:09:24 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-11 17:09:24 -0500 |
| commit | 45194e5e5cb73dd4fc583c4d8ac753034c57d1ba (patch) | |
| tree | 120d319fb6dc912d4bb06f501e33f9926fcc2738 /inbox | |
| parent | d52e73aa4b9a2db8f830ae833e83479e3763ab8f (diff) | |
| download | rulesets-45194e5e5cb73dd4fc583c4d8ac753034c57d1ba.tar.gz rulesets-45194e5e5cb73dd4fc583c4d8ac753034c57d1ba.zip | |
chore: process home consolidation handoffs and file follow-ups
Diffstat (limited to 'inbox')
3 files changed, 401 insertions, 0 deletions
diff --git a/inbox/PROCESSED-2026-06-11-1703-from-home-consolidation-handoff-rulesets.org b/inbox/PROCESSED-2026-06-11-1703-from-home-consolidation-handoff-rulesets.org new file mode 100644 index 0000000..f0a86b7 --- /dev/null +++ b/inbox/PROCESSED-2026-06-11-1703-from-home-consolidation-handoff-rulesets.org @@ -0,0 +1,46 @@ +#+TITLE: Home is consolidating all personal ~/projects AI projects into itself — heads-up + okay requested +#+DATE: 2026-06-11 + +* What's happening + +Craig approved and started a migration that folds every AI-managed project under ~/projects (except work) into the home project as area subdirectories, with full git history preserved via git filter-repo + merge. End state: ~/projects holds home and work only; ~/code stays the place for standalone code projects. One todo.org, one priority scheme, one .ai session for all personal project management. + +The spec rode along in this same inbox drop (from-home file with "project-consolidation-spec" in the name). It went through a full spec-review cycle (Codex, two passes: Not ready → Ready) and carries the per-fold manifest contract, a two-mode restore runbook, and a layered rollback story (snapper snapshot, untouched server bares, pre-fold tags, retired dirs, 30-day cooling-off). + +* How far we've gone (as of 2026-06-11 ~17:00 CDT) + +- Phase 0 done: git-filter-repo verified, snapper snapshot 5621, memory-dir tar in ~/backups/, pre-consolidation tag pushed. +- Phase 1 done: philosophy folded (pilot). Mode-B rollback drill passed in a disposable clone — the fold is provably removable using only its manifest. +- Phase 2 done: clipper folded (dress rehearsal). First todo.org import with :MIGRATED_FROM: markers and a fold-time triage; first live-link fix (a dirvish bookmark in ~/.emacs.d). +- Both sources retired to ~/projects/.retired/ (not deleted). Server bares untouched. +- Manifests at home:docs/consolidation-manifest-{philosophy,clipper}.org; live inventory gate at docs/consolidation-manifest-inventory.org. + +* Learnings and adjustments so far + +- A manifest can't embed its own redistribution commit's sha (amend changes it). The manifest row now reads "the commit introducing this manifest"; only the merge sha is recorded literally. +- git clone --no-local is the right clone shape for filter-repo's fresh-clone safety check; --force is banned from the runbook. +- The fold-merge branch is read from the source (fb-photo-scraper sits on master, not main — assume nothing). +- Staged freeze instead of full shutdown: the live inventory gate is regenerated per project immediately before its fold, so Craig can keep using not-yet-folded projects until their turn. +- Imported [#D] tasks fall outside the task-review staleness pool (it tracks A-C only) — by design, but worth knowing when verifying an import. +- Source todo.org "Reference" sections (non-task content) merge into the area's notes.org, not into home's todo.org. + +* What we'd like rulesets to think about + +- Edge cases we may not have seen: anything in the templates, workflows, or scripts that assumes one .ai per project under ~/projects (cross-agent-comms discovery, inbox-send target resolution, the ai launcher's project scan, broadcast). +- Future-project plans: whether new personal "projects" should now start as areas inside home rather than standalone ~/projects entries, and whether the templates should say so. +- Any rulesets docs or workflows that name the folding projects as handoff/broadcast targets (finances, jr-estate, etc.) — they'll need updating in our Phase 7 ecosystem pass; a list from your side would help us not miss any. +- The knowledge-base work-root denylist (~/projects/work) is unaffected. + +* Ask: confirmed okay to continue + +Reply to home's inbox with a confirmed okay (or concerns) for folding the remaining projects. The remaining list, in planned order: + +1. jr-estate (Phase 3 — 704M history, 18-task triage, first memory merge) +2. danneel (Phase 4 — 613M history, 10-task triage) +3. finances (Phase 5 — 251M history, 43-task triage) +4. documents, elibrary, health, kit (Phase 6 folds, together) +5. website + little-elisper — relocate to ~/code as standalone AI projects (Phase 6) +6. fb-photo-scraper — delete (unmodified upstream clone; origin recorded in spec D2) +7. Phase 7 ecosystem pass: link sweep, velox migration, rulesets-reference updates, KB node, cooling clock. + +We hold the remaining folds until your reply lands. diff --git a/inbox/PROCESSED-2026-06-11-1703-from-home-project-consolidation-spec.org b/inbox/PROCESSED-2026-06-11-1703-from-home-project-consolidation-spec.org new file mode 100644 index 0000000..b557012 --- /dev/null +++ b/inbox/PROCESSED-2026-06-11-1703-from-home-project-consolidation-spec.org @@ -0,0 +1,350 @@ +#+TITLE: Project Consolidation — Fold ~/projects AI Projects into Home — Spec +#+AUTHOR: Craig Jennings +#+DATE: 2026-06-11 + +* Metadata +| Status | Ready — Codex spec-review confirmed 2026-06-11 | +| Owner | Craig Jennings | +| Reviewer | Codex (spec-review, 2026-06-11) | +| Related | [[file:../todo.org::*Project consolidation into home][todo.org task]] | + +* Summary + +Fold every AI-managed project under =~/projects/= (except =work=) into the =home= project as area subdirectories, with full git history preserved, so all personal tasks live in one =todo.org= and can be prioritized against each other. The end state: =~/projects/= holds =home= and =work=; =~/code/= holds standalone code projects. Every step is reversible — originals are snapshotted, server bare repos stay untouched until a cooling-off period ends, and a written restore procedure covers both single-project and full rollback. + +* Problem / Context + +Craig manages 12 AI projects under =~/projects/= beside =home= and =work=. Each has its own =.ai/= session machinery, =todo.org=, inbox, memory dir, and git repo on cjennings.net. That isolation was the design — but the life-management projects (finances, jr-estate, danneel, health, kit, clipper, documents…) are all facets of one life, and their tasks compete for the same hours. Today there is no single surface where a [#A] in jr-estate can be weighed against a [#A] in finances; each project's priorities are graded against siblings only. Sessions fragment the same way: a morning touching finances, danneel, and home means three separate session launches, three inboxes, three memory stores, and cross-project handoff files between them. + +The forces: (1) one prioritization surface requires one task file (or at least one repo); (2) these projects are critical — legal disputes, estate settlement, finances — so the migration must be provably reversible; (3) per-project git histories carry evidentiary and reference value (especially danneel and jr-estate) and must survive queryably; (4) the =.ai/= ecosystem (sessions, memories, inboxes, workflows) has per-project state that must merge without loss; (5) other machines (velox at minimum) hold clones whose remotes must not break silently. + +Survey of the candidates (2026-06-11): + +| Project | What it is | .git | Sessions | Open tasks | Memories | Inbox | +|------------------+---------------------------------------------+-------+----------+------------+----------+-------| +| clipper | 19 Clipper St SF rental property | 23M | 6 | 1 | 0 | 0 | +| danneel | 4319 Danneel construction dispute (legal) | 613M | 45 | 10 | 0 | 0 | +| documents | Disaster-prep document vault | 61M | 7 | 8 | 0 | 2 | +| elibrary | Ebook + music library management | 2.4M | 6 | 0 | 2 | 3 | +| fb-photo-scraper | Third-party FB gallery scraper (clone) | 3.4M | 0 | 0 | 0 | 0 | +| finances | Personal finance (Craig + Christine) | 251M | 24 | 43 | 1 | 4 | +| health | Personal health management | 5.9M | 27 | 8 | 1 | 3 | +| jr-estate | JR estate settlement (legal, trust, taxes) | 704M | 44 | 18 | 7 | 2 | +| kit | Keep In Touch — relationship management | 17M | 20 | 20 | 3 | 4 | +| little-elisper | The Little LISPer worked in elisp (study) | 4.7M | 2 | 0 | 0 | 0 | +| philosophy | Philosophy study + discussion notes | 30M | 5 | 0 | 0 | 0 | +| website | Personal Hugo site (deployed from homelab) | 8.6M | 10 | 11 | 0 | 3 | + +All have origin on cjennings.net except fb-photo-scraper (GitHub clone). All =.ai/= dirs are tracked (personal-project model). No project has a live =session-context.org=. Several have small dirty trees (elibrary 2, finances 1, health 1, kit 4, little-elisper 1 files) that must be resolved pre-fold. + +* Goals and Non-Goals + +** Goals +- One repo, one =todo.org=, one priority scheme, one =.ai/= session for all personal (non-work) project management. +- Full git history of every folded project preserved and queryable in place (=git log <area>/= works). +- All =.ai/= state merged without loss: session archives, memories, inboxes, someday-maybe, project workflows/scripts. +- A written, tested restore path for any single project and for the whole migration. +- =~/code/= becomes the only home for standalone code projects. + +** Non-Goals +- No restructuring of home's existing content (homelab docs, assets, music reconciliation dirs stay where they are; re-nesting them under an =infra/= area is vNext). +- No change to the =work= project in any way. +- No task content rewriting beyond re-grading priorities to the unified scheme — bodies, links, and histories move as-is. +- No server-side bare-repo deletion during the migration (archival is a separate, later, post-cooling step). +- No renaming of the =home= project. + +** Scope tiers +- v1: fold the nine life-management projects (clipper, danneel, documents, elibrary, finances, health, jr-estate, kit, philosophy); relocate the code-shaped three (website, little-elisper, fb-photo-scraper) per Decision 2; ecosystem updates (emacs agenda, rulesets references, velox). +- Out of scope: work; any =~/code/= project; home's internal restructure. +- vNext: server bare-repo archival after cooling-off; optional =infra/= re-nesting of homelab content; per-area README normalization. + +* Design + +** End-state layout + +Each folded project becomes a top-level area directory in home, preserving its internal structure: + +#+begin_example +~/projects/home/ + clipper/ danneel/ documents/ elibrary/ + finances/ health/ jr-estate/ kit/ philosophy/ + assets/ docs/ homelab-inventory/ inbox/ scripts/ (existing home content, unchanged) + todo.org (unified) + .ai/ (single session machinery) +#+end_example + +This matches the established area pattern (work's =deepsat/assets/=, the working-files convention's =<area>/assets/=). Each area keeps its own =assets/=, =docs/=, internal org files, and a per-area =.gitignore= carrying its old ignore patterns (git honors nested ignores; prefixing patterns into the root ignore is error-prone). + +** Git history — filter-repo then merge + +For each source project, on a throwaway clone (never the original). =--no-local= forces a real transport-style clone instead of hardlinked/shared objects — the conservative shape git-filter-repo's manual recommends, and what makes the clone a genuine fresh-clone safety check. =branch= is the source's actual default branch (fb-photo-scraper is on =master=; assume nothing): + +#+begin_example +branch=$(git -C ~/projects/<name> symbolic-ref --short HEAD) +git clone --no-local ~/projects/<name> /tmp/fold-<name> +cd /tmp/fold-<name> +git filter-repo --to-subdirectory-filter <name> +cd ~/projects/home +git remote add fold-<name> /tmp/fold-<name> +git fetch fold-<name> +git merge --allow-unrelated-histories -m "feat(<name>): fold <name> project into home" "fold-<name>/$branch" +git remote remove fold-<name> +#+end_example + +=git filter-repo --force= is not part of this runbook. If filter-repo refuses to run, the fresh-clone safety check failed — stop, write down why, and fix the clone rather than overriding. + +=filter-repo= rewrites every historical path under =<name>/=, so after the merge =git log <name>/somefile= shows the file's full history with original commit messages, authors, and dates. The original repo and its server bare are never touched — the rewrite happens on the temp clone only. + +The merged home =.git= grows to roughly 1.8G (dominated by danneel 613M + jr-estate 704M + finances 251M). Acceptable for a private single-user server; noted as a clone-time cost. + +** The .ai/ and task merge (per project, after the git merge) + +The git merge lands the project's files under =<name>/=, including its old =.ai/= and =todo.org=. A post-merge commit then redistributes that state: + +1. /Sessions:/ =git mv <name>/.ai/sessions/*= into home's =.ai/sessions/=, inserting the area into the name: =YYYY-MM-DD-HH-MM-<desc>.org= → =YYYY-MM-DD-HH-MM-<name>-<desc>.org=. Dated names make collisions near-impossible; the prefix preserves provenance. +2. /todo.org:/ append the project's open work as a new top-level section =* <Area> Open Work= (matching =* Home Open Work=), and its resolved section likewise. Each imported section heading carries a properties drawer marking provenance — =:MIGRATED_FROM: <name>= and =:MIGRATED_ON: YYYY-MM-DD= — so the import boundary stays visible to future edits and to the restore runbook. Walk the incoming tasks with Craig to re-grade priorities onto the unified scheme (home's A-D impact/urgency ladder, generalized beyond infra) and add an area tag (=:finances:=, =:jrestate:=, =:danneel:=, …). Then delete =<name>/todo.org=. +3. /notes.org:/ the project's Project-Specific Context moves to =<name>/notes.org= (area-local reference, linked from home's =.ai/notes.org=). Active Reminders and Pending Decisions merge into home's =.ai/notes.org= with area attribution. +4. /Inbox:/ process each project's inbox to zero before the fold (preferred), or move unprocessed items into home's =inbox/= renamed =YYYY-MM-DD-from-<name>-<orig>.ext=. +5. /Workflows + scripts:/ copy =<name>/.ai/project-workflows/*= and =project-scripts/*= into home's, after a filename-collision check (13 workflow files exist across sources; any collision is resolved by area-prefixing the incoming file). Then delete the area's old =.ai/= machinery (=protocols.org=, =workflows/=, =scripts/= — all template-synced duplicates). +6. /someday-maybe.org:/ append under an =* <Area>= header in home's. +7. /Memory:/ copy =~/.claude/projects/-home-cjennings-projects-<name>/memory/*.md= into home's memory dir (rename on slug collision), append index lines to =MEMORY.md=, dedupe against existing entries, then archive the source memory dir into the backup tar (it lives outside git). +8. /Links:/ =grep -rn "projects/<name>" ~/projects/home ~/.emacs.d ~/sync/org ~/org/roam= and fix every absolute reference to the new path. Record the before-count, fix, re-run, and classify any remaining hits as historical (session archives, this spec) or live — live hits block the fold's close. Relative links inside the area survive the move untouched because internal structure is preserved. + +** Per-fold manifest + +Every fold produces a tracked manifest at =docs/consolidation-manifest-<name>.org=, written as the fold proceeds and committed with the redistribution commit. The manifest is the restore contract and the verification record — without it, "every step is reversible" is a slogan. It records: + +- /Source state:/ source path, HEAD sha, branch, =git status --porcelain=v1= output at gate time (must be empty), origin URL. +- /Tracked universe:/ the =git ls-files= listing from the source (or a sha256 of it, with the listing in an appendix block). After the merge, every path must exist under =home/<name>/= or appear in the redistribution map below. +- /Untracked, ignored, and inbox inventories:/ each file listed with its explicit disposition — processed, moved (to where), archived, or intentionally dropped. Nothing leaves the source tree without a line here. +- /Redistribution map:/ sessions moved (old → new names), todo.org section markers added (=:MIGRATED_FROM:= headings), notes/someday-maybe merges, workflows/scripts copied (with collision resolutions), memory files copied + =MEMORY.md= lines added, link rewrites made (=path:line=, before → after). +- /Commits:/ the fold merge commit sha and the redistribution commit sha. +- /Retired path:/ where the source dir went. + +Verification per fold checks path lists against this manifest, not file counts — a count can pass while losing files and fail on intentional redistribution. + +** Safety net and restore + +Layered, oldest-to-newest: + +- /Layer 0 — filesystem snapshot./ Before anything: =snapper create --description pre-consolidation= (ratio's root is btrfs with snapper) plus a belt-and-suspenders tar of the memory dirs: =tar czf ~/backups/claude-memory-pre-consolidation-$(date +%F).tgz -C ~/.claude projects=. Content-only restore is sufficient for the memory tar — memory files are plain-text markdown the harness reads by path; no permissions, ACL, or xattr metadata is load-bearing, so plain =tar czf= is the contract. +- /Layer 1 — server bare repos untouched./ Origin repos on cjennings.net remain exactly as they are through v1. They hold every byte of every project's history independent of anything done locally. +- /Layer 2 — pre-fold tags./ Home gets =git tag pre-consolidation= before the first fold and =git tag pre-fold-<name>= before each subsequent one, pushed to origin. +- /Layer 3 — retired dirs./ After a fold is verified, the source dir moves to =~/projects/.retired/<name>= (not deleted). Deleted only after the cooling-off period. +- /Cooling-off:/ 30 days minimum after the final fold, and not before velox is migrated. Only then does vNext server archival (move bares to =~/git/archive/=) become eligible. + +*** Restore one project — two modes + +/Mode A — resurrect standalone (leaves home alone)./ =git clone cjennings@cjennings.net:git/<name>.git ~/projects/<name>=, restore its memory dir from the tar. The folded copy in home stays as a harmless duplicate (or is removed later via Mode B). This is the fast path when the need is "I want the project back," not "the fold was wrong." + +/Mode B — remove the folded state from home./ A fold is two commits plus out-of-git side effects; removal must unwind all of it, using the manifest: + +1. =git revert <redistribution-commit>= then =git revert -m 1 <merge-commit>=, in that order (newest first). This is the supported path while the fold is recent — before later edits touch the shared files. +2. If either revert conflicts (todo.org and =.ai/notes.org= are hot files — expected once home has moved on), abort it and instead excise manually from the manifest's redistribution map: delete the =:MIGRATED_FROM: <name>= todo.org sections, the area-prefixed session files, the copied workflows/scripts, and =git rm -r <name>/= — one removal commit citing the manifest. +3. Out-of-git effects either way: delete the copied memory files and their =MEMORY.md= index lines (named in the manifest); re-fix any link rewrites if the old path is coming back. + +/Restore everything:/ snapper rollback (or restore the snapshot's =~/projects/=), restore the memory tar, =git reset --hard pre-consolidation= on home plus a coordinated forced push — acceptable on a single-user remote, with the tag as the anchor. + +** Multi-machine + +velox (and any other machine with clones) keeps working against the untouched server bares until its own migration step: pull home (which brings all folded content), then retire its local =~/projects/<name>= clones the same way. Nothing breaks in the interim — the old remotes still exist; they're just frozen. The =ai= launcher discovers projects by =.ai/protocols.org= presence, so retired dirs (moved under =.retired/=, outside its scan roots) drop out automatically. =inbox-send= targets shrink the same way; any rulesets doc or workflow that names a folded project as a handoff target gets updated in the final phase. + +* Alternatives Considered + +** Keep separate repos, unify only the agenda (org-agenda-files spanning all todo.orgs) +- Good, because zero migration risk and Craig's emacs agenda can already span files. +- Bad, because it solves only prioritization-viewing, not management: 10 sessions, 10 inboxes, 10 memory stores remain; Claude still can't see or rebalance the whole picture in one session; cross-project handoffs persist. +- Bad, because priority schemes stay divergent per file. +- Neutral, because it could serve as an interim state, but it builds nothing toward the end goal. + +** git subtree add per project +- Good, because one command per fold, no external tooling. +- Bad, because history isn't path-rewritten: =git log <name>/file= doesn't follow into pre-merge history without =--follow= gymnastics, weakening the evidentiary value of danneel/jr-estate histories. +- Neutral, because content-wise the result is identical; only history ergonomics differ. + +** Import working trees only, archive old repos (no history merge) +- Good, because the home repo stays small and the procedure is trivially simple. +- Bad, because in-place history is lost — every "when did this clause change" question requires resurrecting an archived repo. +- Neutral, because Layer-1 bares preserve history regardless; this is about whether history is /at hand/. + +** One new "life" super-repo instead of growing home +- Good, because a clean slate avoids home's existing 109M history and infra identity. +- Bad, because home is already the hub (biggest session history, the template patterns, Craig's habits) and would itself need folding in — strictly more work for a cosmetic gain. + +* Decisions + +** D1 — Merge strategy: filter-repo + merge per project +- State: accepted +- Context: critical legal/financial histories must stay queryable in place; restore must be possible regardless. +- Decision: We will fold each project with =git filter-repo --to-subdirectory-filter= on a temp clone, merged with =--allow-unrelated-histories=. +- Consequences: easier — full per-area history in one repo, originals untouched; harder — home =.git= grows to ~1.8G, and =git-filter-repo= becomes a migration dependency (AUR: =git-filter-repo=). + +** D2 — Disposition of the code-shaped three +- State: accepted (Craig, 2026-06-11) +- Context: website (Hugo codebase), little-elisper (code study), fb-photo-scraper (third-party clone, no .ai) are code-shaped, and the target model says code lives standalone in =~/code/=. +- Decision: We will move website and little-elisper to =~/code/= as standalone AI projects (plain =mv= + memory-dir rename, same as the homelab→home rename runbook), and delete fb-photo-scraper (it's an unmodified upstream clone — re-cloneable from =https://github.com/budavariam/traverse_facebook_galleries.git=, branch =master=; recorded here so the proof survives the deletion). +- Consequences: easier — =~/projects/= reaches the clean end state (home + work); harder — website's 11 open tasks stay in their own todo.org, outside the unified prioritization (acceptable: they're code tasks, not life tasks). + +** D3 — Unified todo.org: one file, per-area top-level sections +- State: accepted +- Context: cross-area prioritization wants one surface; the staleness script, agenda, and review workflows all operate on one file today. +- Decision: We will keep a single =todo.org= with =* <Area> Open Work= top-level sections mirroring =* Home Open Work=, unified under home's A-D priority scheme, with area tags on every imported task. +- Consequences: easier — one review rotation, one grep, one agenda file covers everything; harder — the file grows to roughly 5-6k lines (~110 incoming open tasks), so reads lean on Grep/offset and the section discipline matters more. + +** D4 — Per-area task triage at fold time +- State: accepted +- Context: each project graded priorities against siblings only; merging without re-grading would make cross-area priorities meaningless. +- Decision: We will walk each incoming area's open tasks with Craig at fold time, re-grading to the unified scheme (the task-review walk shape, applied per area). +- Consequences: easier — the unified list is trustworthy from day one; harder — the big folds (finances at 43 tasks) cost a real review session each. + +** D5 — Cooling-off before any destruction +- State: accepted +- Context: "if it goes south, I need a way to restore." +- Decision: We will destroy nothing for 30 days after the final fold: source dirs go to =~/projects/.retired/=, server bares stay, snapshots and tags persist. fb-photo-scraper deletion (D2) is the one exception — it's an unmodified upstream clone. +- Consequences: easier — every layer of the restore path stays live through the risky window; harder — ~2G of retired duplicates sit on disk for a month. + +* Implementation phases + +Each phase ends with a working tree, a pushed commit, and a verification gate. One project per session is the expected pace; phases 3+ are repetitions of the runbook proven in phase 2. + +** Phase 0 — Pre-flight (global prep; gates per project at its turn) +Install =git-filter-repo=. Snapper snapshot + memory-dir tar. Tag and push =pre-consolidation= on home. + +The *live inventory gate* lives at =docs/consolidation-manifest-inventory.org= and is regenerated *per project, immediately before that project's fold* — not all at once. Craig keeps using not-yet-folded projects (staged freeze), so a single up-front table would go stale by Phase 3; the per-fold regeneration is the gate. Fields per project: default branch, origin URL, dirty count (=git status --porcelain=), ahead/behind vs upstream, inbox file count, =session-context.org= presence, memory file count, project-workflow/-script names (collision candidates), and disposition (fold / relocate / delete / out-of-scope). The gate passes only when: clean tree, ahead/behind 0/0, inbox empty, no live session-context. A failing project gets fixed (wrap, commit, process, push) and its row regenerated before its fold begins. + +D2 is resolved (2026-06-11); no open decisions remain in this phase. + +** Phase 1 — Pilot fold: philosophy +Smallest life project, no todo.org, no memories, empty inbox. Run the full fold runbook (git merge + redistribution + manifest + verification). Then the *rollback drill*: in a disposable =--no-local= clone of home (or a throwaway branch), run the Mode-B removal runbook against the pilot's manifest and verify the folded state is fully gone — sessions, workflows, =<name>/= tree. Discard the clone. The legal and financial folds must never be the first test of the removal story. This phase hardens the runbook appendix; expect to amend the spec from what's learned (history entry, not rewrite). + +** Phase 2 — Dress rehearsal: clipper +Nearly as small (23M, no memories, empty inbox) but adds the one runbook path the pilot can't exercise: the todo.org import — =* Clipper Open Work= section, =:MIGRATED_FROM:= markers, and a one-task triage with Craig. After this phase every runbook step has run at least once except the memory merge (premieres in Phase 3; lowest-risk step — plain file copies outside git, tar-backed). + +** Phase 3 — jr-estate +The priority fold. 704M history, 18-task triage, 44 sessions, and the first memory merge (7 files). One session. + +** Phase 4 — danneel +613M history, 10-task triage, 45 sessions, 1 project-workflow. One session. + +** Phase 5 — finances +251M history and the heaviest triage (43 tasks). One session, possibly two if the triage runs long. + +** Phase 6 — Remaining folds + code relocations (together) +Fold documents, elibrary, health, kit (~36 incoming tasks, elibrary/health/kit memories, kit's 4 project-workflows collision-checked). Move website and little-elisper to =~/code/= (mv + memory-dir rename per the homelab→home runbook); delete fb-photo-scraper (origin recorded in D2). After this phase =~/projects/= contains home, work, and =.retired/=. + +** Phase 7 — Ecosystem pass +Fix every absolute-path reference (emacs config, org-roam, agenda-files, bookmarks, rulesets docs naming folded projects as inbox-send/cross-agent targets). Migrate velox (pull home, retire its clones). Write the KB node recording the new layout. Start the 30-day cooling clock; file a dated vNext task for server bare archival and =.retired/= deletion. + +* Acceptance criteria + +- [ ] =~/projects/= contains exactly =home=, =work=, and =.retired/=. +- [ ] For each folded project, =git log --oneline <name>/ | tail= in home shows its earliest original commits. +- [ ] Manifest parity per fold: every path in the source's =git ls-files= listing exists under =home/<name>/= or appears in the manifest's redistribution map; every untracked/ignored/inbox file has a recorded disposition. Path-list comparison, not counts. +- [ ] =todo.org= passes org-lint; every imported task carries an area tag and an A-D priority Craig re-graded; imported sections carry =:MIGRATED_FROM:= markers. +- [ ] =task-review-staleness.sh --list todo.org 20= run after each fold surfaces the imported area's tasks as depth-2 review units alongside existing areas (proves the rotation spans the whole list). +- [ ] Per fold: source memory basenames diffed against home's memory dir and =MEMORY.md= entries — all accounted for; source memory dirs are in the backup tar. +- [ ] Link-rewrite check per fold: the before-grep count is recorded in the manifest, and the after-grep over =~/.emacs.d ~/sync/org ~/org/roam ~/projects/home= returns only hits classified historical (session archives, this spec) — zero live links. +- [ ] Layer-1 restore drill passes: clone one folded project from its untouched server bare into =/tmp=, confirm it's whole. +- [ ] Mode-B rollback drill (Phase 1 pilot) passes: the pilot fold is fully removable from a disposable clone using only its manifest. +- [ ] A fresh Claude session in home can answer "what are my top 5 tasks across all areas?" from the unified todo.org. +- [ ] velox runs a clean session in home post-migration with no stale-remote errors. + +* Readiness dimensions + +- Data model & ownership: every file keeps its owner (Craig); =.ai/= state redistributes per the merge map above; memory dirs are the one store outside git — covered by the tar in Phase 0 and the copy step per fold. +- Errors, empty states & failure: every fold step is git-tracked, so a failed fold is =git reset --hard <pre-fold tag>= plus re-running from the temp clone (which is rebuilt from scratch each attempt). filter-repo failures abort before anything touches home. +- Security & privacy: all content stays on the private cjennings.net remote; no new exposure surface. The merged repo concentrates sensitive material (legal + financial + health) in one clone — same machines, same threat model as today. +- Observability: each fold is one merge commit + one redistribution commit, tagged; progress is the phase checklist in todo.org; verification gates are the acceptance criteria run per-fold. +- Performance & scale: ~1.8G final =.git=; clone cost noted. todo.org at 5-6k lines stays well within Grep/offset workflows. No runtime performance surface. +- Reuse & lost opportunities: reuses the homelab→home rename runbook (memory-dir rename, link sweep), the task-review walk for triage, snapper for snapshots, and the established area-dir pattern. git-filter-repo over hand-rolled rewrites. +- Architecture fit & weak points: area dirs match the working-files convention. Weak point: the =.ai/= redistribution is manual and per-project — mitigated by the pilot phase hardening a written runbook before the critical folds. +- Config surface: none — no knobs. The one dependency is the =git-filter-repo= package. +- Documentation plan: this spec is the migration doc; the fold runbook and manifest template live in the appendix below (refined by the Phase 2 pilot); the KB node in Phase 6 records the end state for all future agents. +- Dev tooling: N/A because the migration is one-shot; the runbook commands in Design are the tooling. +- Rollout, compatibility & rollback: staged per-project rollout, multi-machine sequencing (velox last), layered rollback (snapshot / untouched bares / tags / retired dirs), 30-day cooling before any destruction. Dry-run equivalent: the pilot fold. +- External APIs & deps: =git-filter-repo= (AUR, stable, widely used — verify installed in Phase 0). No network APIs. + +* Risks, Rabbit Holes, and Drawbacks + +- /Link rot is the long tail./ Absolute =file:= links to old project paths can lurk in org-roam, emacs bookmarks, calendar event descriptions, and Keep notes. The Phase 6 grep covers the file-based stores; Keep and calendar references can't be grepped — accept that stragglers get fixed on encounter. +- /todo.org scale./ 5-6k lines is fine for tools, but the agenda view gets dense. If it becomes noise, the vNext escape hatch is per-area =#+CATEGORY= or splitting resolved sections to an archive file — not re-splitting projects. +- /Triage fatigue./ Re-grading ~110 tasks is the human bottleneck. Mitigation: it's split across the fold phases, and each area's walk uses the existing 7-at-a-time review muscle. +- /Workflow collisions./ 13 project-workflow files across sources; names look distinct but the check is mandatory per fold. +- /The merged repo is a bigger blast radius./ A bad force-push or corrupting operation now touches everything. Mitigation: the same layered backups, plus home already carries this responsibility for its own content. +- /Drawback accepted:/ per-project session isolation disappears — one project's noisy session history now shares a dir with everything. The area prefix on archived session names keeps provenance. + +* Appendix — Fold runbook (per project) + +Refined by the Phase 2 pilot; until then this is the v0 contract. Every step either succeeds with the expected output or the fold stops — no improvising past a failed step. + +1. /Gate./ Regenerate the project's row in the live inventory (Phase 0 fields). Require: clean =git status --porcelain=, ahead/behind 0/0, inbox empty, no =session-context.org=. Fix and regenerate, or stop. +2. /Manifest open./ Create =docs/consolidation-manifest-<name>.org= from the template below; fill source state and the =git ls-files= listing; inventory untracked/ignored files with dispositions. The Redistribution row reads "the commit introducing this manifest" — a commit sha can't be embedded in its own commit (pilot learning, 2026-06-11); the merge sha is known beforehand and is recorded literally. +3. /Tag./ =git tag pre-fold-<name> && git push origin pre-fold-<name>=. +4. /History fold./ The filter-repo + merge block from Design (with =--no-local=, =$branch=, no =--force=). Record the merge sha in the manifest. +5. /Redistribute./ Steps 1-8 of the =.ai/= and task merge map, recording each move in the manifest's redistribution map as it happens. One commit; record its sha. +6. /Verify./ Manifest parity (path lists), org-lint on todo.org, staleness-script check, memory diff, link before/after grep. All green or the fold stops here for repair. +7. /Retire./ =mv ~/projects/<name> ~/projects/.retired/<name>=; record the path. Push home. + +** Manifest template + +#+begin_example +,#+TITLE: Consolidation manifest — <name> +| Source path | ~/projects/<name> | +| Origin | <url> | +| Branch / HEAD | <branch> / <sha> | +| Gate state | clean / 0-0 / inbox 0 / no session-context | +| Merge commit | <sha> | +| Redistribution | <sha> | +| Retired to | ~/projects/.retired/<name> | + +,* Tracked universe +<git ls-files output, or sha256 + appendix> + +,* Untracked / ignored / inbox dispositions +| file | disposition (processed / moved-to / archived / dropped) | + +,* Redistribution map +- Sessions: <old> → <new> … +- todo.org: section ":MIGRATED_FROM: <name>" added at <heading> +- Workflows/scripts copied: <names + collision resolutions> +- Memory: <files copied> + MEMORY.md lines added +- Link rewrites: <file:line before → after> + +,* Link grep +- Before: <count> | After: <count, all classified historical> +#+end_example + +* Review dispositions + +Findings from the 2026-06-11 Codex review (review file deleted on processing per spec-response). Modified items below; *everything else was accepted as written* — H1 (manifest + redistribution-aware restore), H2 (path-list verification, porcelain gate, find-prune fix by removal), H3 (=--no-local=, no =--force=), H4 (live inventory gate), M2 (pilot rollback drill), M3 (fb-photo-scraper re-clone pointer), the UX provenance markers, the documentation appendix, and the memory/link verification commands. + +- /M1 (memory tar metadata) — modified:/ the review offered preserving metadata or declaring content-only sufficient. Chose content-only: memory files are plain-text markdown the harness reads by path; no permissions/ACL/xattr metadata is load-bearing. Stated in Layer 0 rather than adding =--xattrs --acls=. +- /Test strategy item 2 (staleness fixture test) — modified:/ a live =task-review-staleness.sh --list todo.org 20= check after each fold replaces a new fixture-based unit test. The script already has its own bats suite; the migration-specific question ("are imported area tasks depth-2 review units?") is answered better by the live check on the real file, per fold, than by a one-shot fixture. +- /Open question 2 (revert vs manifest-removal as the supported runbook) — modified:/ the "choose one" framing doesn't survive the time axis. Supported path: revert both commits (redistribution first) while the fold is recent; once shared files have moved on and reverts conflict, the manifest-driven removal commit is the path. Both are now written in Restore Mode B; the manifest makes the fallback safe, which is why it exists. + +* Review and iteration history + +** 2026-06-11 Thu @ 15:11:32 -0500 — Claude Code (home, with Craig) — author +- What changed: re-sequenced the implementation phases to Craig's chosen order — philosophy pilot, clipper dress rehearsal (added as its own phase so the todo.org-import path is proven before real data), then jr-estate → danneel → finances by urgency, with the remaining folds + code relocations merged into one closing phase before the ecosystem pass. Phase 0's live inventory gate is now explicitly per-project-at-its-turn, matching the staged-freeze approach (Craig keeps using not-yet-folded projects until their turn). +- Why: Craig wants the critical legal/financial projects consolidated early after a proven runbook, and chose staged freeze over a full shutdown. The clipper rehearsal closes the gap where the pilot (no todo.org) never exercises task import. +- Artifacts: todo.org phase tasks re-sequenced to match. + +** 2026-06-11 Thu @ 14:13:49 -0500 — Codex — reviewer +- What changed or was recommended: assigned =Ready= after re-running spec-review against the incorporated spec; no further blocking review notes and no new review file. +- Why: the prior blockers are now covered by the per-fold manifest contract, live inventory gate, =--no-local= filter-repo runbook, redistribution-aware restore, Phase 2 rollback drill, and manifest-based acceptance criteria. +- Artifacts: this spec; [[file:../todo.org::*Project consolidation into home][todo.org tracking task]] updated with Ready status and implementation phase tasks. + +** 2026-06-11 Thu @ 13:20:54 -0500 — Claude Code (home) — responder +- What changed: all four blocking findings accepted and woven in — =--no-local= + no-=--force= runbook with a =$branch= variable (H3, H4's master/main catch), a Per-fold manifest section as the restore/verification contract (H1, H2), two-mode single-project restore covering the redistribution commit (H1), Phase 0 live inventory gate (H4), Phase 2 Mode-B rollback drill (M2), manifest-parity acceptance criteria replacing file counts (H2), fb-photo-scraper re-clone pointer in D2 (M3), =:MIGRATED_FROM:= provenance markers (UX), runbook appendix + manifest template (docs). Three points modified with reasons in Review dispositions; nothing rejected. +- Why: the review's core finding was right — restore and verification only covered the history merge, not the redistribution commit and the untracked-file universe. The manifest is the single artifact that fixes both. +- Artifacts: review file (deleted on processing); dispositions section above; todo.org tracking task updated. + +** 2026-06-11 Thu @ 13:09:29 -0500 — Codex — reviewer +- What changed or was recommended: assigned =Not ready= and wrote a blocking review focused on exact rollback semantics, per-fold manifests, live inventory gating, =git clone --no-local= for filter-repo safety, and stronger verification than raw file counts. +- Why: the design direction is sound, but implementation would still require inventing how to unwind redistributed =.ai/=, =todo.org=, inbox, and memory state safely after each fold. +- Artifacts: review file deleted during the response pass; retained via the dispositions section above. + +** 2026-06-11 Thu @ 12:08:03 -0500 — Claude (with Craig) — author +- What: initial draft. +- Why: Craig asked for a consolidation design with restore guarantees — one prioritization surface for all personal projects. +- Artifacts: survey data gathered live from ~/projects on ratio; todo.org task cross-linked. diff --git a/inbox/PROCESSED-2026-06-11-1705-from-home-addendum-to-today-s-consolidation.org b/inbox/PROCESSED-2026-06-11-1705-from-home-addendum-to-today-s-consolidation.org new file mode 100644 index 0000000..392b844 --- /dev/null +++ b/inbox/PROCESSED-2026-06-11-1705-from-home-addendum-to-today-s-consolidation.org @@ -0,0 +1,5 @@ +#+TITLE: Addendum to today's consolidation handoff: first concrete to +#+SOURCE: from home +#+DATE: 2026-06-11 17:05:20 -0500 + +Addendum to today's consolidation handoff: first concrete tooling edge case found. todo-cleanup.el --archive-done assumes exactly one level-1 'Open Work' and one 'Resolved' heading per todo.org; home's consolidated file now has per-area pairs (Home Open Work / Home Resolved, Clipper Open Work / Clipper Resolved, more coming) and the pass skips with 'more than one level-1 heading contains Open Work'. Suggested fix: match each '* <Area> Open Work' with its '* <Area> Resolved' sibling and archive within the pair, falling back to current behavior for single-pair files. Until then home archives manually at wrap-up. |
