Skip to content

instantiate.sh & adopt.sh: closing-message guidance + CLAUDE.md content + README announcement gaps after bootstrap #63

Description

@psaboia

Observation

After a successful adopt --apply [--github-wiki], the script ends with:

Applied: 45 file(s) created in <target>
Manifest written to .llm-wiki-adopt-log.md
Review the result with: git -C <target> status && git -C <target> diff

That covers "review", but the four things a new adopter actually needs to do next are nowhere on screen:

  1. There are now TWO git repos with separate flows. The host repo received the 45 ADD files plus TOUCH grants and is committable / pushable through the host's normal workflow. The wiki sub-repo at wiki/<name>.wiki/ is a separate repo with its own remote (configured automatically by --github-wiki). Commits and pushes on the wiki have to be invoked with git -C wiki/<name>.wiki/ .... A first-time adopter who does not know this can:

    • Accidentally git add wiki/<name>.wiki/ thinking it is just a directory (caught by the .gitignore sentinel block, but only if they read it).
    • Write wiki content and never push it, never realising the agent's edits live in a sub-repo that has not been shared.
  2. init-wiki --github adds a local commit to the wiki sub-repo that is not yet on GitHub. The output of the adoption test on a FUNSD scratch clone (f061064 Initialize wiki with llm-wiki pattern (namespaced)) sat on top of the existing wiki history locally; teammates browsing the GitHub Wiki UI still see only the pre-existing pages until someone runs git -C wiki/<name>.wiki/ push. The adoption appears complete to the user but the namespaced nav files are not visible to the team yet.

  3. CLAUDE.md and .claude/settings.json were modified in-place (managed-block injection and JSON merge respectively). These are high-trust operations, already flagged by review on PR adopt.sh: orchestrator for first-time wiki-memory adoption into existing repos #51. The user should review the diff before committing — but the closing message only suggests git diff, not "review CLAUDE.md / .claude/settings.json specifically before commit."

  4. Practical entry points are absent. Nothing tells the user "open Claude Code in this directory and try /wiki-experiment / /wiki-source / /wiki-lint" — the slash commands and skills are installed but their discoverability depends on the user reading .claude/commands/ themselves.

  5. Host-side .gitignore collisions are silently invisible. Adopt installs .claude/commands/, .claude/skills/, and .claude/settings.json into the host. If the host's pre-existing .gitignore excludes .claude/ (common reflex — many teams treat .claude/ as per-user by default), the overlay files are installed on disk but git status does not surface them. CLAUDE.md ends up referencing slash commands that the host's git tree does not carry; teammates clone the host repo, get the CLAUDE.md, try the slash commands, and find nothing. The adopter has no warning that this happened — both adopt and git status cooperate to make the gap invisible. Empirical case surfaced 2026-06-28 during the manual adoption dogfood (issue init-wiki --github silently overwrites Home.md when cloning a wiki that has pre-existing content #66 comment thread documents the host repo state).

  6. instantiate.sh has the same problem on a different surface. Instantiate prints a fixed closing block (edit CLAUDE.md, edit README, optional --hook, commit, open agent) that predates the slash-command ecosystem and the wiki-* skill family (wiki-migrate, wiki-archaeology, wiki-synthesize are all in flight or proposed). A first-time user of an instantiated project sees no mention of /wiki-experiment, /wiki-source, /wiki-lint in the terminal output — even though instantiate just installed them. Same root cause as observations 1-5 (script terminates without sufficient guidance), different script.

  7. CLAUDE.md content is asymmetric between the two bootstrap paths. When instantiate.sh renders CLAUDE.md.template, the result includes skeleton sections — ## What this repository is and ## Conventions when editing — with placeholder instructions for the human ("Write a short paragraph here describing what this project does..."). When adopt.sh runs and the host already has a CLAUDE.md, adopt only injects the two sentinel blocks (lw:memory-boundary, lw:wiki-maintenance) and leaves the rest of the file alone — the human-prompt scaffolding never appears for adopters. Result: instantiate users get the prompts that tell them to add project context; adopt users don't. Open design question: should adopt also inject a third managed-block (e.g., lw:project-context) with the same placeholder prompt, or surface that prompt only in the Next-steps block?

  8. No README announcement snippet. Neither script touches the host's README.md (correct — README is host-owned), and neither prints a copy-pasteable announcement the human can choose to paste in. A teammate cloning the project after adoption (or instantiation) sees no signal from the README that the wiki-memory pattern is in play; they discover it only by opening CLAUDE.md or noticing the wiki sub-repo. The fix is not to modify README — it is to print a suggested snippet in the Next-steps block ("Optional: paste this into your README near the top if you want the pattern visible at clone time") that the user copies manually. Same treatment makes sense in both adopt and instantiate.

How it surfaced

Manual end-to-end test of the Bloco 2 recipe during PR #60 review-resolution (FUNSD scratch clone, --apply --github-wiki, wiki already materialized on GitHub). The technical run worked perfectly — 45 ADDs, 3 TOUCHes, init-wiki cloned the existing wiki with origin pre-configured, overlay setup ran, exit 0. The gap was UX: a reviewer asking "is it clear how the user should proceed?" answered no.

Filed alongside the closing of the manifest-consolidation Open Question; the manifest is the structural fix, and "Next steps" is the human-readable bookend that the structural fix made coherent enough to write.

Fix sketch

Append a Next steps block at the very end of scripts/adopt.sh's apply branch, before exit 0. Conditional on what actually ran (do not advertise wiki-push steps if init-wiki failed; do not point at slash commands if --agent=none).

The fix should also include a pre-commit warning: when the host's .gitignore matches .claude/ or any of the overlay-installed paths and the overlay's files would not be tracked by git, surface a loud advisory in the Next steps block:

Advisory: your .gitignore excludes .claude/ (or .claude/commands, .claude/skills,
.claude/settings.json). The wiki-memory overlay files were installed locally but
will not be tracked by git, so teammates cloning this repo will not receive the
slash commands CLAUDE.md references. Decide before commit:
  - Team-shared: edit .gitignore to un-ignore the overlay subset, e.g.
      .claude/*
      !.claude/commands/
      !.claude/skills/
      !.claude/settings.json
      (.claude/settings.local.json stays ignored — per-user, Anthropic convention)
  - Per-user only: leave .gitignore as-is; each teammate runs adopt individually.

The advisory is informational, not blocking — the adopter may genuinely want the per-user behaviour.

Mirror the Next-steps block in instantiate.sh (covers observation 6)

instantiate.sh should print the same shape of conditional Next-steps block, adapted to what it just ran (--agent, --features, --github-wiki, --dev-self). The current fixed closing block becomes the fallback for unrecognised configurations; the conditional block becomes the default. Implementation should share the assembler with adopt.sh via a small helper (e.g. scripts/lib/next-steps.sh exposing lw_next_steps_for adopt|instantiate <flags>), so the two scripts cannot drift on what they tell the user.

For instantiate specifically, the block should include:

  • "Open Claude Code in this directory and try: /wiki-experiment, /wiki-source, /wiki-lint" (currently missing)
  • "Read CLAUDE.md and fill in the ## What this repository is and ## Conventions when editing sections" (the placeholder prompts the template already ships)
  • If --features= was passed: how to verify each feature is active
  • If --github-wiki was passed: the same wiki sub-repo push instructions adopt produces

Address the CLAUDE.md content asymmetry (covers observation 7)

Two options:

Option A — adopt injects a third managed-block. Add lw:project-context as a new sentinel-paired block that adopt injects into CLAUDE.md alongside the existing two. The block contains the same placeholder prompt that CLAUDE.md.template ships (e.g. "Write a short paragraph here describing what this project does, who it is for, and what state it is in"). Idempotent: only injected when the sentinel is absent. Pro: discoverable from the first read of CLAUDE.md. Con: more intrusive on existing CLAUDE.md content.

Option B — surface the prompt in Next-steps only. Adopt prints "Open CLAUDE.md and add a '## What this project does' section near the top — same prompt instantiate.sh uses for new projects." in its Next-steps block. Pro: conservative, no auto-injection. Con: relies on the user remembering or re-running the closing message.

Recommendation: Option B for the first cut (smallest blast radius), Option A behind a feature flag (--inject-project-context) for adopters who want the prompt to live in CLAUDE.md persistently. Both scripts get the Option B suggestion in their Next-steps; instantiate already injects this via the template, so it does not need Option A.

Print a README announcement snippet (covers observation 8)

Both adopt's and instantiate's Next-steps block should include a clearly marked optional snippet, e.g.:

Optional: paste this into your README near the top if you want the pattern
to be visible at clone time (neither adopt nor instantiate modifies your
README; it is host-owned):

  > This project uses the [llm-wiki-memory pattern](https://github.com/crcresearch/llm-wiki-memory-template).
  > Wiki lives at `wiki/<name>.wiki/` (separate git repo). Agent context
  > in `CLAUDE.md`. Try `/wiki-experiment`, `/wiki-source`, `/wiki-lint` in
  > a Claude Code session.

Marked "optional" so the user can ignore it; the snippet is template-friendly (substitute <name> with $REPO_NAME at print time).

A minimum useful block for the common case (--apply [--github-wiki] --agent=claude-code):

Next steps:
  1. Review the host changes:
       git status
       git diff CLAUDE.md .claude/settings.json     # high-trust modifications
       git diff                                      # full diff
  2. Commit the host changes:
       git add -A && git commit -m "adopt llm-wiki-memory-template"
       git push                                      # if you are ready to share
  3. The wiki sub-repo is a separate git repo with its own remote already configured:
       git -C wiki/<name>.wiki/ log --oneline -3     # inspect the bootstrap commit
       git -C wiki/<name>.wiki/ push origin master   # share the namespaced files with the team
       (Run separately from the host's git operations. The host's .gitignore excludes
        wiki/<name>.wiki/ so the host never tries to track it.)
  4. Open Claude Code in this directory and try:
       /wiki-experiment   - register an experiment or milestone in the wiki
       /wiki-source       - capture a paper or external source
       /wiki-lint         - health-check pages and cross-references

Variations:

  • If init-wiki: applied (local-only) (no --github-wiki, no remote configured): step 3 becomes Configure a remote later if you want to share the wiki: git -C wiki/<name>.wiki/ remote add origin <url> && git -C wiki/<name>.wiki/ push -u origin master.
  • If --agent=none: step 4 omits the slash commands and instead says "Open whichever agent you use in this directory; the CLAUDE.md tells it how to use the wiki."
  • If github-wiki: failed (seed-push 404, fell back to local init): step 3 includes the UI-creation instruction that the fallback path already prints to stderr, but pulled forward into the Next steps block so it is unmissable.

Acceptance

  • A first-time adopter (someone who has not contributed to the template repo) runs adopt --apply and can complete a working setup, including sharing the wiki content with their team, using only what is printed on stdout (no need to read CLAUDE.md, the wiki page, or the source of adopt.sh).
  • Each of the three init-wiki dispatch outcomes (applied (--github mode, cloned), applied (local-only), failed (--github-wiki seed-push 404)) produces a Next steps block that matches the actual installed state — no instructions that point at a remote that was not configured, no missing instructions for the manual-remote-configuration path.
  • Existing integration fixtures continue to pass (assertions match stderr / manifest patterns, not the closing block).
  • Optionally: a small fixture asserting the Next steps block contains the expected sub-repo push instruction when --github-wiki succeeded and omits it when it did not.
  • instantiate.sh prints a conditional Next-steps block of the same shape (covers observation 6); shares the assembler with adopt to prevent drift.
  • Adopt's Next-steps block surfaces the "fill in CLAUDE.md's project-context section" prompt for adopters whose hosts already had CLAUDE.md (covers observation 7, Option B); Option A (lw:project-context managed-block) is behind a feature flag if implemented.
  • Both adopt and instantiate Next-steps blocks include an optional, marked-as-optional README announcement snippet (covers observation 8). Neither script auto-modifies README; the snippet is for manual paste.

Context

Surfaced during PR #60 manual adoption test (Bloco 2 recipe: --apply --github-wiki against a FUNSD scratch clone where the wiki was already materialized). Adopt completed cleanly; the question "fica claro como o usuário deve proceder?" surfaced this gap. Cousin issue to #61 (posttooluse-hook substitution defect) and #62 (scripts/kg/ drift) — all three originated in the same manual validation pass that the manifest consolidation enabled.

Refs: PR #60 (manifest introduction; "Out of scope" references this UX-polish surface); PR #59 (--github-wiki flag; the three dispatch outcomes this fix has to cover); PR #51 (the high-trust managed-block injection that step 1 of Next steps points at explicitly).

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