Defect
wiki/init-wiki.sh:204-211 writes a redirect stub into Home.md:
# --- Write Home.md redirect (GitHub wiki landing page) ---
if [[ ! -f "$WIKI_DIR/Home.md" ]] || ! grep -qF "redirect" "$WIKI_DIR/Home.md" 2>/dev/null; then
cat > "$WIKI_DIR/Home.md" << REDIRECTEOF
<!-- redirect: this file exists for GitHub wiki compatibility -->
<!-- The real home page is ${HOME_NS}.md -->
See [${PROJECT_NAME}](${HOME_NS})
REDIRECTEOF
fi
The condition [[ ! -f Home.md ]] || ! grep -qF "redirect" Home.md is intended to be idempotent: leave the file alone on re-runs (where Home.md already has "redirect"), create it on first run (where the file is absent). But it has a third path that is silently destructive:
When init-wiki --github clones an existing GitHub wiki that has a substantive Home.md (no "redirect" marker in it), the script overwrites that file with the stub. No warning, no diff, no opportunity for the user to decline.
When this matters
adopt --apply --github-wiki against a project whose GitHub Wiki was used ad-hoc before adopting the llm-wiki pattern:
- Team had been using GitHub Wiki as a regular wiki, authored
Home.md as a real landing page (e.g. project summary, links to other pages).
- They decide to adopt the llm-wiki pattern.
- Run
adopt --apply --github-wiki. Phase 2B clones the existing wiki, then init-wiki silently rewrites Home.md with the redirect stub.
- Their original landing-page content is gone, both locally and on push to GitHub.
The pattern's other namespaced files (index_<repo>.md, log_<repo>.md, SCHEMA_<repo>.md) protect against this with the if [[ ! -f ... ]] guard alone (no grep -qF fallback path). Only Home.md has the second condition that triggers destruction.
How it surfaced
Discovered while explaining the GitHub Wiki "first page" UI step for the virgin-adopt quick start (issue #64's Quick start section). For the virgin case, the overwrite is the correct behaviour: the user wrote a placeholder ("test") to materialize <repo>.wiki.git on GitHub, and init-wiki replacing that placeholder with the redirect is what should happen. For the non-virgin case (real Home.md content), the same overwrite is silently destructive.
Bloco 2 manual test of PR #60 against a FUNSD scratch (wiki already materialized with three pre-existing pages) saw the Home.md on disk become 135 bytes after init-wiki ran — the redirect stub, not whatever FUNSD's prior Home.md content may have been. The three other pre-existing pages were preserved correctly; only Home.md was clobbered.
Fix sketches
Option A — preserve and rename. Detect Home.md exists, lacks "redirect", and was likely host-authored (e.g. has substantive content beyond a one-liner). Rename to Home-original.md (or Home.host-authored.md) and then write the redirect stub. Lossless. The host can move content into Home_<repo>.md (the real namespaced home) afterwards, or link to Home-original from there.
Option B — refuse loudly. If Home.md exists and lacks "redirect", lw_die with an explicit message: "Existing Home.md detected at $WIKI_DIR/Home.md. The llm-wiki pattern uses Home.md as a redirect to Home_.md. Either delete Home.md (its content will be lost) or move its content into Home_.md before continuing." Forces the user to make a deliberate choice. Less ergonomic but never destructive without consent.
Option C — diff and prompt (interactive). Show the diff between the existing Home.md and the redirect stub, prompt for [k]eep / [o]verwrite / [m]ove-to-Home_<repo>. Most flexible, but interactive mode is awkward inside adopt --apply which is meant to be scriptable.
Option D — skip if not empty. If Home.md exists with any content, leave it alone. Loses the redirect benefit (GitHub UI users land on the host's old Home.md, not the namespaced one), but never destructive.
Recommendation: Option A (preserve and rename) is the most lossless. It is also the most consistent with the rest of init-wiki's defensive posture (e.g. index_<repo>.md is "create-only-if-absent" — never overwrites). The cost is one extra file in the wiki sub-repo (the renamed original) that the host can clean up at leisure.
A hybrid is possible: Option A by default, with --force-overwrite-home (or similar) restoring the current overwrite behaviour for the case where the host really does want to discard the existing Home.md.
Acceptance
init-wiki --github against a wiki whose Home.md is substantive and lacks the "redirect" marker either:
- (a) preserves the original (Option A: rename + write stub; user sees the rename in the adopt log), OR
- (b) refuses with a loud error pointing at the exact file and the resolution path (Option B), OR
- (c) some other non-destructive resolution.
- The virgin case continues to work: a tiny placeholder Home.md (from a one-time UI step) is replaced by the redirect stub without ceremony.
- Idempotency holds: re-running adopt or init-wiki against a wiki that already has the redirect Home.md is a no-op.
- A test fixture under
scripts/test/tests/integration/ or scripts/test/tests/smoke/ exercises both paths (virgin vs non-virgin Home.md) and asserts the appropriate outcome for each.
Context
Pre-existing defect, predates PR #60 and the manifest consolidation. Surfaced during the documentation pass for issue #64 (quick start for the virgin-adopt case) while explaining what the "first page in the UI" placeholder content becomes after adopt: it gets overwritten. That answer is correct for the virgin case but exposes the silent destruction for the non-virgin case.
Adopt-side flow that triggers this: adopt --apply --github-wiki against a host whose GitHub Wiki has already been used ad-hoc. The init-wiki --github invocation in adopt's Phase 2B is where the overwrite happens.
Refs: PR #60 (manifest introduction; the manual adoption test surfaced this), #64 (the quick start that documents the virgin-case overwrite as expected behaviour and needs to flag the non-virgin destruction once this is fixed), #63 (the Next steps block could include "your previous Home.md content was preserved at Home-original.md" if Option A is chosen).
Defect
wiki/init-wiki.sh:204-211writes a redirect stub intoHome.md:The condition
[[ ! -f Home.md ]] || ! grep -qF "redirect" Home.mdis intended to be idempotent: leave the file alone on re-runs (whereHome.mdalready has "redirect"), create it on first run (where the file is absent). But it has a third path that is silently destructive:When
init-wiki --githubclones an existing GitHub wiki that has a substantiveHome.md(no "redirect" marker in it), the script overwrites that file with the stub. No warning, no diff, no opportunity for the user to decline.When this matters
adopt --apply --github-wikiagainst a project whose GitHub Wiki was used ad-hoc before adopting the llm-wiki pattern:Home.mdas a real landing page (e.g. project summary, links to other pages).adopt --apply --github-wiki. Phase 2B clones the existing wiki, then init-wiki silently rewritesHome.mdwith the redirect stub.The pattern's other namespaced files (
index_<repo>.md,log_<repo>.md,SCHEMA_<repo>.md) protect against this with theif [[ ! -f ... ]]guard alone (nogrep -qFfallback path). OnlyHome.mdhas the second condition that triggers destruction.How it surfaced
Discovered while explaining the GitHub Wiki "first page" UI step for the virgin-adopt quick start (issue #64's Quick start section). For the virgin case, the overwrite is the correct behaviour: the user wrote a placeholder ("test") to materialize
<repo>.wiki.giton GitHub, and init-wiki replacing that placeholder with the redirect is what should happen. For the non-virgin case (realHome.mdcontent), the same overwrite is silently destructive.Bloco 2 manual test of PR #60 against a FUNSD scratch (wiki already materialized with three pre-existing pages) saw the
Home.mdon disk become 135 bytes after init-wiki ran — the redirect stub, not whatever FUNSD's priorHome.mdcontent may have been. The three other pre-existing pages were preserved correctly; onlyHome.mdwas clobbered.Fix sketches
Option A — preserve and rename. Detect
Home.mdexists, lacks "redirect", and was likely host-authored (e.g. has substantive content beyond a one-liner). Rename toHome-original.md(orHome.host-authored.md) and then write the redirect stub. Lossless. The host can move content intoHome_<repo>.md(the real namespaced home) afterwards, or link toHome-originalfrom there.Option B — refuse loudly. If
Home.mdexists and lacks "redirect",lw_diewith an explicit message: "Existing Home.md detected at $WIKI_DIR/Home.md. The llm-wiki pattern uses Home.md as a redirect to Home_.md. Either delete Home.md (its content will be lost) or move its content into Home_.md before continuing." Forces the user to make a deliberate choice. Less ergonomic but never destructive without consent.Option C — diff and prompt (interactive). Show the diff between the existing Home.md and the redirect stub, prompt for
[k]eep / [o]verwrite / [m]ove-to-Home_<repo>. Most flexible, but interactive mode is awkward insideadopt --applywhich is meant to be scriptable.Option D — skip if not empty. If
Home.mdexists with any content, leave it alone. Loses the redirect benefit (GitHub UI users land on the host's old Home.md, not the namespaced one), but never destructive.Recommendation: Option A (preserve and rename) is the most lossless. It is also the most consistent with the rest of init-wiki's defensive posture (e.g.
index_<repo>.mdis "create-only-if-absent" — never overwrites). The cost is one extra file in the wiki sub-repo (the renamed original) that the host can clean up at leisure.A hybrid is possible: Option A by default, with
--force-overwrite-home(or similar) restoring the current overwrite behaviour for the case where the host really does want to discard the existing Home.md.Acceptance
init-wiki --githubagainst a wiki whoseHome.mdis substantive and lacks the "redirect" marker either:scripts/test/tests/integration/orscripts/test/tests/smoke/exercises both paths (virgin vs non-virgin Home.md) and asserts the appropriate outcome for each.Context
Pre-existing defect, predates PR #60 and the manifest consolidation. Surfaced during the documentation pass for issue #64 (quick start for the virgin-adopt case) while explaining what the "first page in the UI" placeholder content becomes after adopt: it gets overwritten. That answer is correct for the virgin case but exposes the silent destruction for the non-virgin case.
Adopt-side flow that triggers this:
adopt --apply --github-wikiagainst a host whose GitHub Wiki has already been used ad-hoc. Theinit-wiki --githubinvocation in adopt's Phase 2B is where the overwrite happens.Refs: PR #60 (manifest introduction; the manual adoption test surfaced this), #64 (the quick start that documents the virgin-case overwrite as expected behaviour and needs to flag the non-virgin destruction once this is fixed), #63 (the
Next stepsblock could include "your previous Home.md content was preserved at Home-original.md" if Option A is chosen).