Skip to content

ADOPTING.md + Adopter-Runbook wiki page: end-to-end instructions for external adopters #64

Description

@psaboia

Observation

The template has rich documentation surfaces (README.md for maintainers, wiki/llm-wiki-memory-template.wiki/ for designers, the per-overlay wiki/agents/<agent>/README.md for users of each overlay), but no surface that answers the specific question: "I have an existing GitHub project. Tell me what to do, step by step, to adopt this pattern, without me having to read any of those other docs."

Real symptom: during PR #60 review-resolution, after adopt --apply --github-wiki was verified end-to-end on a FUNSD scratch clone and worked perfectly, the question "fica claro como o usuário deve proceder com o comando de apply nesse caso?" answered no. The script's output, the wiki design page, and the README between them tell you what adopt does — none of them tell an external collaborator the operational sequence: prerequisites, the decision they have to make about --github-wiki, the review-before-commit obligation, the two-repo model, the smoke test, and the recovery path when something fails.

The "send this email and the collaborator can do it" surface is the missing piece.

Why the existing surfaces don't cover this

Surface Audience Why insufficient for an adopter
README.md Template maintainer, person evaluating the pattern Focuses on "what is this and how do I create a project from it"; adoption is one paragraph
wiki/llm-wiki-memory-template.wiki/Adopt-Existing-Repo-Design.md Designer thinking about adopt's architecture Reads as design rationale, not as an operational procedure
wiki/agents/claude-code/README.md (and cursor's) Someone configuring a specific overlay AFTER adoption Pre-supposes the wiki sub-repo and CLAUDE.md sentinels already exist
Adopt's own stdout The person running the command Reports what happened; does not narrate what to do next (also tracked in #63)

Decision: two-surface split

  • ADOPTING.md at the repo root (operational, scannable, the "30-second answer" + the actual commands). This is what gets linked in an onboarding email. Path: crcresearch/llm-wiki-memory-template/blob/main/ADOPTING.md.
  • Adopter-Runbook wiki page (deep, troubleshooting, flowcharts, worked example, glossary). Linked from ADOPTING.md for users who hit edge cases or want context.

Rationale: shallow entry point + deep reference is a familiar shape (think CONTRIBUTING.md + a developer wiki). Two surfaces means more to maintain, but the alternative — one monolithic ADOPTING.md — fails both audiences: too long for the email path, too thin for the troubleshooting path.

Proposed initial content

ADOPTING.md

# Adopting llm-wiki-memory-template into an existing project

This is the runbook for adopting the wiki-memory pattern into a project that already exists. For a new project, use [Use this template → Create repository] on the GitHub UI and run `scripts/instantiate.sh` instead.

For background on what "adopt" does internally, see the Adopt-Existing-Repo-Design wiki page. For troubleshooting and recovery scenarios, see the Adopter-Runbook wiki page.

## Prerequisites

The literal content to put under "Prerequisites" in `ADOPTING.md` — an executable checklist the adopter pastes into a terminal before running the Quick start.

```bash
# === PREREQUISITES (check before running) ===

# 1. SSH key works for github.com
ssh -T git@github.com    # expected: "Hi <user>! You've successfully authenticated"

# 2. You are in the right repo, with origin pointing at GitHub
cd <existing-project>
git remote -v            # expected: origin git@github.com:<owner>/<project>.git

# 3. Working tree is clean (no uncommitted or untracked files)
git status --porcelain   # expected: EMPTY
# If anything shows, pick one:
#   git stash --include-untracked    (restore later with git stash pop)
#   OR
#   git add -A && git commit -m "WIP before adopt"

# 4. (Confirm) Wiki is enabled in the repo's settings
#    https://github.com/<owner>/<project>/settings -> Features -> Wikis = ON

# 5. (Confirm) Inspect .gitignore — does it exclude .claude/ or wiki/?
grep -E '^\.claude|^wiki' .gitignore
# If yes: see "Implementation note: surgical .gitignore pattern" below
# before commit. Do not just widen the un-ignore to !.claude/commands/
# and !.claude/skills/ — that exposes unrelated per-user content.
```

`git` and `bash` 3.2+ are assumed; both are present on any system where git itself works. macOS bash 3.2.57 is the lower bound for portability (validated; see template-bootstrap fixture).

## Implementation note: surgical `.gitignore` pattern (for the writer of ADOPTING.md, not for the adopter)

This expands on prerequisite #5 above. The advice "use a surgical pattern, not broad" is the load-bearing recommendation; the rationale and failure modes belong in this note (not in the adopter's checklist) because they are spec-meta — the adopter follows the recipe, the writer of ADOPTING.md needs to know why the recipe is shaped the way it is.

If `.gitignore` already excludes `.claude/`, the overlay files adopt installs (`.claude/commands/wiki-*.md`, `.claude/skills/wiki-*.md`, `.claude/settings.json`) will be installed on disk but silently invisible to git, so they will not reach teammates on clone. Decide before commit:

- **Per-user only**: leave `.gitignore` as-is; each teammate runs adopt individually. CLAUDE.md will reference slash commands the team does not have unless every teammate adopts.
- **Team-shared (surgical pattern)**: un-ignore ONLY the specific wiki overlay paths, not the whole `.claude/commands/` or `.claude/skills/` subtrees:

  ```
  .claude/*
  !.claude/commands/
  .claude/commands/*
  !.claude/commands/wiki-experiment.md
  !.claude/commands/wiki-source.md
  !.claude/commands/wiki-lint.md
  !.claude/skills/
  .claude/skills/*
  !.claude/skills/wiki-experiment.md
  !.claude/skills/wiki-source.md
  !.claude/skills/wiki-lint.md
  !.claude/settings.json
  ```

  `.claude/settings.local.json` stays ignored by `.claude/*` (per-user, Anthropic convention).

Why surgical instead of broad (`!.claude/commands/` + `!.claude/skills/`): `.claude/commands/` and `.claude/skills/` on existing hosts commonly contain pre-existing per-user content unrelated to the wiki-memory overlay — tool-managed skills installed by external installers (often as symlinks into a gitignored `.agents/skills/` or similar directory), hand-authored personal commands for individual workflow, skills installed from the Anthropic marketplace deliberately kept per-user. Widening the un-ignore broadly stages all of that pre-existing content for the next commit, by accident. Two concrete failure modes:

1. *Broken symlinks for teammates.* Tool-managed skills often install the real content under `.agents/skills/<name>/` (gitignored) and place a symlink at `.claude/skills/<name>` pointing back to it. Committing the symlink without its target produces a dangling reference on every teammate's clone. Surfaced 2026-06-28 during the manual adoption dogfood (the host had a tool-managed `langfuse` skill installed as such a symlink; the broad `!.claude/skills/` pattern staged it; the surgical pattern correctly re-ignored it).
2. *Silent over-share of intentionally per-user content.* The original `.gitignore` of the host treated `.claude/skills/` as "tool-managed local installs" by deliberate convention. Adopt is a one-time event but its `.gitignore` change is persistent; widening too far also captures whatever the host's teammates add to `.claude/commands/` or `.claude/skills/` later, breaking the per-user invariant they may rely on. Surgical un-ignore keeps the broader convention intact.

Empirical case surfaced 2026-06-28 during the manual adoption dogfood: a host whose `.gitignore` had `.claude/` ignored saw adopt install the slash commands successfully but `git status` did not show them; CLAUDE.md ended up promising functionality the team would not have received without a `.gitignore` change, and a broad `!.claude/skills/` pattern incorrectly staged an unrelated tool-managed symlink that needed unstaging before commit. The surgical pattern above resolves both.
## Validation status (must appear at top of ADOPTING.md)

> Only the Claude Code path has been end-to-end validated (verified on a FUNSD scratch clone during PR #60 review-resolution: `adopt --apply --github-wiki --agent=claude-code`, init-wiki cloned the existing wiki with origin pre-configured, overlay setup ran, smoke test via `/wiki-experiment` succeeded). The `--agent=none` minimal path is shipped but unverified in a live adopt session; report findings via an issue if you exercise it.

## Quick start (headline path — virgin repo, GitHub-hosted, claude-code overlay, shared wiki)

This is the headline recipe the document opens with, before the detailed Steps 1-6. It targets the most common adopter: an existing GitHub-hosted project with no wiki and no memory yet. Symmetric in shape with `instantiate.sh`'s existing quick start (`README.md` Section 2), explicit about every flag the validated path uses.

```
Quick start (adopt into an existing GitHub-hosted repo with no wiki and no memory):

# One-time-per-project: materialize the GitHub Wiki.
#   open https://github.com/<owner>/<project>/wiki
#   click "Create the first page" (title must be Home; content is throwaway,
#   adopt overwrites it with a redirect to Home_<project>.md), save.
# This step makes <project>.wiki.git materialize as a real, clonable/pushable
# repository on GitHub's side. GitHub does not create <repo>.wiki.git until
# a page exists in the UI.

# Get the template scripts locally (any path; /tmp is fine, just for the run):
git clone https://github.com/crcresearch/llm-wiki-memory-template /tmp/llm-wiki-template

# From inside your existing project:
cd <existing-project>
bash /tmp/llm-wiki-template/scripts/adopt.sh --target=. --apply --agent=claude-code --github-wiki
```

What happens, in order:
1. Phase 1 ADD: 45 files installed (manifest's SHARED_INFRA + OVERLAY_CLAUDE)
2. Phase 2A TOUCH: `CLAUDE.md` created from canonical (you had none), `.gitignore` gains the `lw:wiki-rules` sentinel block with `wiki/*.wiki/`, `.claude/settings.json` created from canonical
3. Phase 2B init-wiki --github: clones `<project>.wiki.git` (with just the Home placeholder from the UI), adds namespaced nav files (`Home_<repo>.md`, `index_<repo>.md`, `log_<repo>.md`, `SCHEMA_<repo>.md`, `Edge-Types.md`), `origin` pre-configured on the sub-repo
4. Phase 2B overlay setup: `wiki/agents/claude-code/setup.sh` injects `lw:memory-boundary` and `lw:wiki-maintenance` sentinels into CLAUDE.md
5. Phase 3 merge: SessionStart hook merged into `.claude/settings.json`

Exit 0. Adoption manifest written to `.llm-wiki-adopt-log.md`.

Next steps (until issue #63 lands and adopt prints these itself):
- Review: `git status && git diff CLAUDE.md .claude/settings.json && git diff`
- Commit host: `git add -A && git commit -m "adopt llm-wiki-memory-template" && git push`
- Push wiki sub-repo (separate git repo): `git -C wiki/<project>.wiki/ push origin master`
- Smoke test: open Claude Code in the project root, run `/wiki-experiment register adoption` and confirm the agent creates the page + updates index/Home/log + commits twice.

What if you skip the UI step? `--github-wiki` tries seed-push, receives 404 (`<project>.wiki.git` does not exist yet), falls back to local-init and prints the UI instruction on stderr. Adoption completes successfully but the wiki sub-repo lacks the `origin` configuration; materialize via the UI later, then `git -C wiki/<project>.wiki/ remote add origin git@github.com:<owner>/<project>.wiki.git && git -C wiki/<project>.wiki/ push -u origin master`. The pre-flight UI step exists to avoid this rework.

## Step 1 — decide whether to use --github-wiki

(decision table covering 4 combinations: GitHub host yes/no × want shared wiki yes/no)

## Step 2 — run adopt

Explicit recipe (the validated path):

```bash
git clone https://github.com/crcresearch/llm-wiki-memory-template /tmp/llm-wiki-template
cd <existing-project>
bash /tmp/llm-wiki-template/scripts/adopt.sh --target=. --github-wiki                          # dry-run first
bash /tmp/llm-wiki-template/scripts/adopt.sh --target=. --apply --github-wiki --agent=claude-code
```

Variants (documented inline, not in the headline command):
- `--agent=none` for minimal mode (shipped but unverified)
- omit `--github-wiki` for local-only wiki (configure remote manually later)
- `--agent=cursor` is currently refused at parse-time

## Step 3 — review the high-trust modifications

(git diff CLAUDE.md .claude/settings.json .gitignore; what each modification means; how to revert)

## Step 4 — commit the host changes

(git add -A && git commit && git push)

## Step 5 — the wiki sub-repo is a separate git repo

(git -C wiki/<name>.wiki/ log/push; remote-add fallback for the no--github-wiki case)

## Step 6 — smoke test

(open Claude Code, run /wiki-experiment, verify two-commit-per-log-entry succeeds)

## Troubleshooting

(short list of the 3-4 most common failures with one-line fixes; deeper coverage in the wiki page)

A complete first draft was sketched during issue triage and can be moved here verbatim once the issue is picked up. Key constraint: stay under one screen of scrollable content per step.

Adopter-Runbook wiki page

- Decision flowchart: --github-wiki (yes/no × wiki materialized yes/no = 4 outcomes)
- Two-repo mental model (host vs wiki sub-repo; push/pull flows)
- Pre-adoption inspection (composite signal detector; dry-run as audit)
- Anatomy of .llm-wiki-adopt-log.md
- Common failure scenarios + recovery:
  - SSH key not configured for github.com
  - --github-wiki: 404 fallback path (with UI step)
  - REFUSE on CLAUDE.md / .gitignore / .claude/settings.json
  - init-wiki: permission denied on wiki.git push (org-level wiki disabled, ACL missing)
  - "command not found: gh" when --github-wiki tries the optional has_wiki PATCH
- Update path after adoption (when to run update-from-template.sh; .gitignore advisory; the 17-file delta for PR #51..#60 adopters, with link to PR #60 migration story)
- Worked example: adopting FUNSD step-by-step (real terminal output, real commands)
- Glossary (managed-block / append-only / merge; composite detector; SHARED_INFRA vs OVERLAY_CLAUDE vs HOST_OWNED)

Acceptance

  • An external collaborator who has not contributed to the template repo (and does not know the source) can complete a full adoption end-to-end using only ADOPTING.md on the happy path. They consult the wiki only when something deviates.
  • ADOPTING.md covers the 4 --github-wiki decision combinations explicitly (table or short prose), not as [--github-wiki] with a (see docs).
  • Adopter-Runbook covers at least 4 common failure modes with recovery commands.
  • README.md gains a one-line pointer to ADOPTING.md in the section that currently mentions adoption.
  • Both surfaces reference each other (ADOPTING → wiki for depth; wiki → ADOPTING for the canonical sequence).
  • Cross-validation: the FUNSD adoption test that surfaced this gap should be reproducible by following ADOPTING.md alone, with the wiki only consulted if init-wiki fails.

Context

Surfaced during the PR #60 manual adoption test pass (Bloco 2 recipe: --apply --github-wiki against a FUNSD scratch clone where the wiki was already materialized). The technical run was clean (exit 0, 45 ADDs, 3 TOUCHes, init-wiki cloned the existing wiki with origin pre-configured, overlay setup ran, smoke test via /wiki-experiment in a Claude Code session passed end-to-end). The gap was UX: a maintainer asking "what would I tell a collaborator?" had no single artifact to point to.

Cousin issues from the same manual-validation pass: #61 (posttooluse-hook substitution defect), #62 (scripts/kg/ drift), #63 (adopt Next steps block at end of --apply). The four together represent the surface that PR #60's manifest consolidation made coherent enough to be auditable; this issue is the documentation half of the same coherence.

Refs: PR #60 (the trigger), #63 (the script-side complement; this issue is the docs-side complement and they should land in close succession), Adopt-Existing-Repo-Design wiki page (the design doc that this runbook lives downstream of).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions