| name | migrate-pai-purpose |
| description | Finish a PAI→Soma migration by placing PAI's imported life-OS content correctly: keep the Purpose compartment as a lean 4-field distillation, promote the rich imported categories (beliefs, mental models, decision frames, challenges, lessons) into Soma memory as recall-able notes, and protect the curated purpose.md from being clobbered. USE WHEN migrating from PAI, after `soma migrate pai`, or a fresh Soma install with imported PAI life-OS files under profile/imports/claude/. |
| metadata | {"short-description":"Place PAI's imported life-OS into Soma Purpose + memory the right way"} |
Migrate PAI's life-OS into Soma Purpose + memory
soma migrate pai moves identity + memory + a mechanical purpose.md. It does not decide where the rest of PAI's imported life-OS belongs, and its identity phase overwrites purpose.md with a raw concatenation each run. This skill finishes the job: it keeps the Purpose compartment lean and curated, and routes the imported breadth into Soma memory where recall can surface it — without bloating the Purpose that ships in every prompt.
Terminology: Soma's compartment is Purpose; the PAI life-OS term for it is killed in Soma (Purpose is the only word). Below, the PAI source directory profile/imports/claude/TELOS/ and its filenames are referenced only as the literal imported artifacts they are.
Core principle
Soma's Purpose is four portable fields — Mission / Goals / Principles / Commitments — the durable "why" projected into every session. PAI's imported life-OS is a ~19-category tree. They are not the same size and must not be conflated:
- Purpose-grade content → distilled into the four Purpose fields (a few lines each).
- Context-grade content (mental models, frames, challenges, lessons, narratives) → Soma memory notes, surfaced on demand by recall.
- Time-bound content (status, projects) → work-state / algorithm-runs, never Purpose.
Never dump whole imported files into purpose.md. The full snapshots already live under profile/imports/claude/; memory notes carry a distillation plus a --source-of-truth pointer back to the snapshot.
Disposition table
Source files live under profile/imports/claude/TELOS/:
| Imported file | Goes to | As |
|---|
MISSION.md (M#) | Purpose → Mission (1–2 sentences) + Goals (the durable M0–Mn) | curated purpose.md |
BELIEFS.md (B#) | Purpose → Principles (the load-bearing few) and a memory note (full B-set) | both |
STRATEGIES.md (S#) + master-narrative filter | Purpose → Commitments (the decision filters) | curated purpose.md |
MODELS.md (MO#) | memory note | semantic |
FRAMES.md (FR#) | memory note | semantic |
CHALLENGES.md (C#) | memory note | semantic |
LEARNED.md | memory note | semantic |
NARRATIVES.md, WISDOM.md, PROBLEMS.md, IDEAS.md, TRAUMAS.md, WRONG.md, PREDICTIONS.md, BOOKS.md, MOVIES.md | memory note iff non-empty (see step 2) | semantic / reference |
STATUS.md, PROJECTS.md | work-state, not Purpose or durable memory | leave in archive |
GOALS.md (G#) | only durable goals → Purpose.Goals; project/time-bound rows → work-state | curated purpose.md |
Procedure
Step 0 — Preconditions
The migration must have run so the snapshots exist:
ls "$SOMA_HOME/profile/imports/claude/TELOS/" # expect MISSION.md, BELIEFS.md, …
If absent, run soma migrate pai --apply first (SOMA_HOME defaults to ~/.soma).
Step 1 — Guard purpose.md (do this FIRST; it is the trap)
soma migrate pai's identity phase regenerates and overwrites profile/purpose.md on every run with a mechanical dump: the Mission: line becomes the source file's unfilled template placeholder, and Goals/Principles/Commitments become raw concatenations of the source GOALS/BELIEFS/STRATEGIES files — each content line prefixed with - , so the source --- separators arrive as - --- lines, alongside tables and ascii diagrams. soma-home.ts reads Mission + section bullets straight from this file, so a clobbered purpose.md propagates garbage into every substrate on the next reproject. (Tracked upstream: purpose.md should be a reserved target — soma#441.)
Step 2 — Skip empty template files
Many imported files ship as unfilled templates (e.g. WISDOM.md, NARRATIVES.md often contain only bracketed placeholders like [Aphorism 1], [Your one-line description], [Quote]). Promote a category only if it has real content:
grep -qE '\[[A-Za-z][^]]*\]|\bYour\b|\[Quote\]|\[Aphorism' FILE # matches → likely a template; inspect before promoting
Read the file; if the substantive sections are placeholders, skip it. Do not create empty notes.
Step 3 — Write one memory note per promotable category
For each non-empty context-grade file, distill it (don't paste the whole file) and write a note. Keep the principal's own voice/language in the body; write the --recall-trigger and description-facing text in the language the assistant reasons in (usually English) so lexical recall matches how topics arise.
soma memory write \
--trigger <see Step 4> \
--id <principal-<category>> --type semantic \
--source-of-truth "profile/imports/claude/TELOS/<FILE>.md" \
--recall-trigger "<one line: what this is + WHEN to surface it>" \
--links "<sibling ids, comma-separated>" \
--body "<a distilled few-line summary, one bullet per numbered item>"
Suggested ids: principal-core-beliefs, principal-mental-models, principal-decision-frames, principal-challenges, principal-lessons-learned. Cross-link siblings with --links so [[id]] graph edges form.
Step 4 — Trust (governance): pick the trigger deliberately
Trust is DERIVED from --trigger; there is no --trust flag. Governance refuses --provenance import under principal trust — imported content cannot silently ride in as principal.
- Principal-in-the-loop (recommended for install/onboarding): show each distilled note to the principal; on their confirmation, write with
--trigger principal-correction --principal-authority (default provenance conversation). This mints principal trust. Per the INDEX admission rule (src/memory-index.ts: a note is admitted if it is principal-trust OR resurfaced-and-verified ≥2×), a principal note's pointer enters INDEX.md on the next reindex and surfaces in every session. The PAI origin stays honest via --source-of-truth.
- Unattended/automated: write with
--trigger import. This mints imported trust: the note is searchable now (soma memory search) and, by the same admission rule, only enters the INDEX after being resurfaced-and-verified ≥2×. Do NOT fake conversation-provenance to force principal trust on bulk imports.
Step 5 — Reindex and verify
soma memory reindex
grep "principal-" "$SOMA_HOME/memory/INDEX.md" # principal-trust notes should be listed
soma memory search --query "conditional yes" # on-demand recall should return the relevant note
If notes were written at principal trust, run a reproject so the projected rules/soma/MEMORY.md bundle (loaded into each session) picks up the new pointers.
How recall surfaces these (set expectations honestly)
- INDEX pointers (always-on): by the admission rule above, principal-trust notes appear in the projected memory bundle every session — the assistant always sees they exist and pulls the full note when relevant. Imported-trust notes appear only after ≥2 resurfaces.
- On-demand search:
soma memory search/recall finds any note by lexical match at any trust — so --recall-trigger/description vocabulary matters.
- There is no per-prompt auto-recall hook today (evented recall is roadmap). So it is "pointers present + full text on recognition/search", not "the exact paragraph auto-appears."
Gotchas
migrate pai re-clobbers purpose.md every run (soma#441) → always re-do Step 1 after migrating.
- Empty templates masquerade as content → Step 2 grep before promoting.
- Don't dump the imported files into
purpose.md → it ships in every prompt; keep it to the four distilled fields.
- Reading
~/.soma (private) while cd'd inside a public tree (e.g. ~/.claude/PAI) trips the fail-closed policy guard as private→public egress → run from a neutral cwd with absolute paths.