# Conversation Transcript - Private-Instance Merge Correction and Issue 30 Session > Source: Claude Code session (`claude-opus-5`), chemenu workspace > Collected: 2026-09-01 > Participant: Torben > Fidelity: **faithful summary transcript, not a verbatim log.** Torben's questions and > instructions are quoted verbatim; the assistant's reasoning is condensed. All shell output > shown was produced by real, disposable test repositories built in a scratch directory during > this session (not the chemenu repository itself) and is reproduced as run. > No credentials appeared in the session. > Third of three transcripts cut from this session; the first two cover the corpus/history work > and the Publish-Remote Gate this one corrects a claim about. Covers Torben asking what actually happens to the demo corpus in a private instance when the upstream changes it - which exposed an unverified, incorrect claim the assistant had just written into `instructions/private-instance.md` the same day. The claim was tested empirically, found wrong, corrected in a released patch (2.2.1), and turned into a properly scoped, tested merge procedure plus a new issue (#30) proposing the fix belongs in the tool itself, or that the upstream should stop shipping content on the branch private instances pull machinery from. --- ## Turn 1 - "was passiert in der privaten instanz nach diesen schema wenn sich upstream der demo-korpus ändert?" The assistant treated this as a request to verify, not answer from the existing text - the previous transcript's `private-instance.md` had said a `git merge upstream/main` would see *deleted-in-ours, unmodified-in-theirs* and resolve silently, which was written as an assumption and never tested. Built a throwaway upstream/private pair of git repos in the scratch directory to test it: private instance deletes the demo corpus once, upstream then modifies one demo page, adds a new one, and deletes another. Ran a plain `git merge upstream/main`. Result, measured rather than assumed: - The upstream's **modified** page produced `CONFLICT (modify/delete)` and left the upstream's version sitting in the working tree - resolving it the obvious way (`git add -A`) would commit that version, bringing the deleted demo page back. - The upstream's **new** page was staged silently. No conflict, no message. - The upstream's **deleted** page (matching a page already deleted on the private side) produced nothing - the one case that actually worked as claimed. The middle case was the one the original claim missed entirely, and it is the dangerous one because nothing announces it - a demo page the upstream adds simply arrives and starts showing up in the private instance's own `lint`, `index`, `search` and `confidence decay`. A second candidate fix was tested and also failed: a `.gitattributes` `merge=ours` driver for `kb/**`/`raw/**`. Same three-scenario test showed the modify/delete conflict still occurred and the new page still landed - the driver only resolves content conflicts on files both sides touch, not modify/delete pairs or additions. ## Turn 2 - Fixing the instruction, in a released patch `instructions/private-instance.md` was rewritten: the "Why a clone rather than a tarball" section now states the measured three-case table instead of the wrong assumption. The update procedure was rewritten to hold the merge open (`git merge --no-commit --no-ff`), force the content stages (`kb/`, `raw/`) back to the pre-merge state while `HEAD` still points at the commit before the merge, commit, and then run an explicit check (`git diff --name-only $BEFORE HEAD -- kb raw` must be empty) - a check the reader cannot silently skip past, unlike a claim they might trust. The bad advice in "Decision points" ("resolve a conflict under kb/ as keep-deleted") was replaced, since that advice is exactly what leads someone to `git add -A` the leaked content. The corrected procedure was itself run against the same three-scenario test plus a fourth (`raw/` alongside `kb/`), and against error paths (dirty working tree rejected, a second run with nothing new to pull is a no-op) - all passing before publishing. Version bumped `2.2.0 -> 2.2.1`. The changelog entry states plainly that the earlier text was "nicht gemessen, sondern angenommen" (not measured, assumed) rather than framing it as a minor wording fix. Published; tests green (752, unchanged in count - this was a documentation fix). ## Turn 3 - "stelle mal ein sauberes skripting hier exemplarisch dar. gibt es alternative setups? könnten wir die demo/test-seiten aus dem repo main irgendwie heraushalten? erstelle aus dem ganzen thema ein issue... aktualisiere/prüfe, ob #3 im gitea sauber ist. prüfe, ob wir sonst alle offenen enden verdrahtet haben." Four asks in one message. Handled in order: **A standalone script**, written and tested (not just described) against the same scenario: rejects a dirty working tree, rejects a concurrent merge/rebase, holds the merge open the same way the instruction's procedure now does, is a no-op on a second run with nothing new, and exits non-zero with a rollback command if the post-merge diff check ever finds leaked content - the check the manual procedure relies on a human to run, made unskippable. **Alternative setups**, and the negative result from Turn 1 (`merge=ours` does not work) was kept rather than omitted, since a rejected alternative is exactly the kind of finding this capture procedure is meant to preserve. **Whether the demo corpus can be kept out of `main` entirely** - assessed as the better fix in principle: the private-instance script (and the instruction's manual procedure) treats a symptom on every downstream instance, repeatedly; keeping content off the branch machinery is pulled from would remove the need for either, by construction, for any new instance. Named as two variants (a separate `demo` branch, or a separate demo repository) with the real cost stated rather than glossed over - `main` becomes a content-free shell, which was the reason the corpus was kept in the first place (as a walkable example), and `nightly.yml`'s corpus lint would need to move. **Issue #30 opened**, carrying the measured table, the working script, both alternatives with their tradeoffs, and the explicit note that it is not a duplicate of #28 but depends on it - #28 is why the corpus moves at all (demo and testbed sharing one `kb/`), #30 is what that movement does to a downstream clone. **Issue #3 checked against its own acceptance criteria** (all five, from the closed issue's own text) rather than assumed closed-and-fine: a grep for the pre-rename name outside history/ changelog/transcripts, presence of a project entity page, the "Thoth" persona note in both `SOUL.md` and its template, and no active technical identifier still using the old name. Found clean - the handful of remaining mentions (`INSTALL.md`, two `kb/` pages) were all phrased as history ("bis 2026-09-01", "damals"), which the criteria explicitly exempt. **The wiring audit** turned up the two gaps described in the second transcript's closing turn (`tools/CONTRACT.md` missing the new gate, `gates.md` not linking to `private-instance.md`) and the stale project-page description - all three fixed in the same pass and published as 2.2.2, verified with `docs verify`, `instructions verify`, `doctor` (16 checks OK), `lint` (clean but for one pre-existing orphan page unrelated to this work), and the full test suite. ## Turn 4 - This capture Torben asked for this session to be captured via `instructions/capture-session.md`, with an explicit instruction to keep private and confidential material out - consistent with, not separate from, everything the day's work had been about. Handled by generalizing every infrastructure and personal-data reference that appeared during the day's audits rather than reproducing the original identifiers, cutting the session into three topic transcripts (this being the third), and filing this transcript's own existence as evidence rather than as new open work - nothing in this turn required a new issue. ## Outcome - **Version:** 2.2.0 -> 2.2.1 -> 2.2.2 - **Commits:** `private-instance.md` correction (2.2.1), documentation wiring + project-page rewrite (2.2.2, shared with the second transcript's closing turn) - **Tests:** 752, green throughout - **Issues:** #30 opened; #3 verified against its own acceptance criteria and confirmed clean, no action needed - **CI:** green after each publish in this transcript's scope