Skip to main content
Status: draft · Version 0.1 · Filed 2026-05-07

version: 0.1 status: draft

SPEC-090 v0.1 — prism_adopt: explicit existing-repository project adoption

Origin

Frank is onboarding existing DFW/Keyz work on Windows mini1. The immediate case is an existing local repo for Keyz4me/Keyz, with related repos/components such as KaiBot and CFD. Today the closest working verb is prism_clone. Its implementation already has a hidden register mode: if project_dir exists and contains .git, it skips git clone and calls backend bootstrap with strategy="register". That works mechanically, but the operator language is wrong. “Clone this repo” and “adopt this repo” are different intents:
  • Clone means the repo is not local yet. Prism performs a checkout.
  • Adopt means the repo already exists locally. Prism binds it into Prism state.
The difference matters because adopting an existing worktree must never clone over, move, reinitialize, or rewrite the application code. The operator should be able to say “adopt this repo” and get a safe register-only path.

§1 — Goals

  1. Add an explicit prism_adopt MCP verb for existing local git repositories.
  2. Keep prism_clone focused on clone/check-out semantics.
  3. Make adoption safe by construction: no git clone, no git init, no code movement, no application-code edits.
  4. Support Windows editor-host onboarding from Cursor/Claude Code/Codex on mini1.
  5. Preserve the existing backend bootstrap behavior by using strategy="register".
  6. Make multi-repo onboarding clear: one Prism project/PID per repo. The GitHub owner/org is repository metadata; it is not the same thing as a Prism org/tenant.

§2 — Non-Goals

  • No monorepo component model in v0.1. If KaiBot and CFD are folders inside the Keyz repo, they are tracked as components/spec areas inside the Keyz Prism project. If they are separate repos, each gets its own Prism project.
  • No automatic mutation during plain prism_start. prism_start may detect an untracked repo and recommend adoption, but adoption remains an explicit verb call.
  • No source-code scaffolding or framework migration. This verb only binds Prism metadata and BIOS/methodology files.
  • No repo creation on GitHub. If the remote does not exist, fail with a clear preflight error.

§3 — Verb Contract

prism_adopt(
  name: string,
  project_dir: string,
  github_repo?: string,
  repo_owner?: string,
  prism_org?: string,
  ptype?: string = "application",
  persona?: string = "Bot",
  force?: boolean = false
)

Required fields

  • name — Prism project display/name slug, e.g. Keyz.
  • project_dir — absolute or workspace-resolved path to the existing local repo.

Optional fields

  • github_repo — canonical repo owner/name or URL, e.g. Keyz4me/Keyz.
  • repo_owner — GitHub owner/org hint, e.g. Keyz4me. This is derived from github_repo when omitted.
  • prism_org — future Prism org grouping hint. In v0.1 this is normally omitted; adoption lands under the current Prism tenant/personal install unless backend project→org binding has shipped.
  • ptype — project type, default application.
  • persona — initial/default persona, default Bot.
  • force — bypass only narrowly defined metadata mismatch guards; never bypasses destructive-code protections.

§4 — Required Preflight

prism_adopt MUST fail before backend mutation unless all required checks pass:
  1. project_dir exists.
  2. project_dir/.git exists.
  3. project_dir is not the Prism repo itself unless name resolves to Prism.
  4. git rev-parse --show-toplevel succeeds and equals/resolves to project_dir, or returns a clear nested-worktree warning. On Windows this comparison MUST canonicalize separators and drive-letter case before comparing.
  5. If github_repo is provided, git remote get-url origin must match it after normalization, or adoption must stop unless force=true.
  6. If github_repo is omitted, try to derive it from origin; if derivation fails, return a structured preflight error asking for github_repo.
  7. If repo_owner is omitted and github_repo has an owner, derive repo_owner from the repo owner. Do not treat the GitHub owner as a Prism org.
  8. If prism_org is provided, preserve it as a future Prism grouping hint only. First-class Prism org enforcement waits for the project→org binding model.
  9. Existing Prism project conflicts are handled explicitly:
    • Same project_dir already bound: return existing PID, idempotent success.
    • Same github_repo already bound to different path: fail with conflict unless force=true and backend supports a safe rebind.
    • Same name already bound to a different repo in the current Prism tenant/personal install: fail with conflict.

§5 — Behavior

On successful preflight:
  1. Call backend project bootstrap with:
{
  "name": "<name>",
  "projectDir": "<project_dir>",
  "strategy": "register",
  "persona": "<persona>",
  "ptype": "<ptype>",
  "githubRepo": "<normalized github_repo>"
}
  1. Load project context by returned PID.
  2. Sync Prism BIOS/methodology files with syncBios({ files: "all", force: false }).
  3. Write no application files except Prism-owned project metadata/docs:
    • PRISM.md
    • AGENTS.md
    • CLAUDE.md
    • no local .prism/project.json binding file in v0.1; backend remains the source of truth
  4. Return a structured result:
{
  "pid": "PID-...",
  "project_dir": "...",
  "mode": "adopt",
  "github_repo": "Keyz4me/Keyz",
  "repo_owner": "Keyz4me",
  "prism_scope": "personal",
  "origin_url": "...",
  "bootstrap_result": {},
  "sync_result": {},
  "next": {
    "start": "prism_start(name=\"Keyz\", identity=\"Cherry\")"
  }
}

§6 — Relationship To prism_clone

Current prism_clone behavior:
Local stateCurrent behavior
Directory missing/empty + repo suppliedClone repo, then bootstrap
Directory exists with .gitRegister existing repo without clone
SPEC-090 changes operator semantics:
VerbIntentAllowed to clone?Requires .git already present?
prism_cloneRemote repo checkout into a local projectYesNo
prism_adoptBind existing local worktree into PrismNoYes
Implementation may initially share helper code with prism_clone, but the public verb contracts stay separate. prism_clone keeps its current existing-repo register fallback for a deprecation window. When that fallback is used after prism_adopt ships, it SHOULD return a warning:
Existing local git repo detected. prism_adopt is the preferred verb for registering existing repos; prism_clone register fallback is retained for compatibility and may be removed in a later v0.2 change.

§7 — Windows / mini1 UX

For an existing repo:
prism_adopt(
  name="Keyz",
  github_repo="Keyz4me/Keyz",
  repo_owner="Keyz4me",
  project_dir="C:\\DATA\\Keyz",
  ptype="application",
  persona="Cherry"
)
persona should refer to an existing persona when possible. For a new operator persona such as Cherry, run prism_persona_create first unless the active backend explicitly supports lazy persona creation during prism_start / controller registration. For three separate repos under a common workspace root:
prism_adopt(name="Keyz",   github_repo="Keyz4me/Keyz",   project_dir="C:\\DATA\\DFW\\Keyz")
prism_adopt(name="KaiBot", github_repo="Keyz4me/KaiBot", project_dir="C:\\DATA\\DFW\\KaiBot")
prism_adopt(name="CFD",    github_repo="Keyz4me/CFD",    project_dir="C:\\DATA\\DFW\\CFD")
For one repo with components:
C:\DATA\DFW\Keyz\
  .git\
  KaiBot\
  CFD\
Adopt only Keyz; track KaiBot and CFD as components/spec areas inside the Keyz project.

§8 — prism_start Integration

prism_start must not silently adopt. It MAY detect the untracked-repo case and return a reminder:
This git repository is not registered as a Prism project. To bind it without cloning or moving files, run prism_adopt(name=..., project_dir=...).
Detection should be advisory only in v0.1.

§9 — Implementation Notes

Likely first implementation is a small refactor in mcp-node/src/verbs/tier1c.ts:
  1. Extract shared helper from prism_clone register path:
    • resolve project dir
    • inspect git remote
    • canonicalize paths cross-platform before comparing project_dir and git rev-parse --show-toplevel
    • call client.bootstrapProjectApi({ strategy: "register" })
    • load context and run syncBios
  2. Add registerVerb({ name: "prism_adopt", ... }).
  3. Add tests for:
    • existing git repo adopts successfully
    • missing dir fails
    • non-git dir fails
    • remote mismatch fails
    • existing binding is idempotent
    • Windows path comparison handles C:\Foo\Bar vs c:/Foo/Bar
    • no git clone command is invoked
Backend/router gap to close before or during implementation: same-path adoption must be idempotent. Before INSERT, the backend bootstrap path should check for an existing project row for (tenant_id, project_dir) and return the existing PID rather than creating a duplicate.

§10 — Acceptance Criteria

  1. On Windows mini1, Cherry can adopt an existing Keyz4me/Keyz checkout from Cursor without cloning.
  2. The adopted project appears in prism_status / prism_start with a PID.
  3. The project receives Prism BIOS files.
  4. Re-running prism_adopt on the same path returns the same PID and does not duplicate project records.
  5. A mismatched origin vs github_repo returns a structured conflict.
  6. Existing prism_clone behavior is not broken.

§11 — Open Questions

  1. Should repo_owner be stored explicitly or derived from normalized github_repo everywhere?
  2. Should prism_clone keep its current register fallback for backward compatibility, or should it start warning that existing repos should use prism_adopt?
  3. When project→Prism-org binding ships, should prism_org become required for hosted/customer-mode adoption?
  • mcp-node/src/verbs/tier1c.ts — current prism_create / prism_clone implementation.
  • SPEC-054 — Node MCP shim / install migration context.
  • SPEC-055 — target registry and operator lifecycle verbs.
  • SPEC-056 — multi-tenant routing / org identity model.
  • SPEC-087 / SPEC-089 — cloud org/auth context for customer onboarding.
Last modified on May 7, 2026