# Dry-run lessons — ch.0 intro (2026-06-09)

## Time spent

Estimates based on session flow; not stopwatch-accurate.

- Pre-flight (Phase 1 — read all 6 protocol docs + persona + template): ~12 min
- Stage 1 emission (Phase 2 — read PDF, identify intro page range, walk paragraphs, emit 9 nodes + edges with full field set): ~35 min
- Stage 2 gap audit (Phase 3 — re-walk + tag every paragraph): ~10 min (low because Stage 1 paragraph-by-paragraph notes pre-staged the tags)
- Adversarial review + resolution (Phase 4 + 5 — self-administered review against 5 checks; 4 flags raised; 3 deliberate + 1 fix): ~20 min
- Post-flight checklist (Phase 6 — schema validation, dedup against bootstrap KG, blind-spot register update): ~8 min
- FigJam population (Phase 7 — create file, attempt structural populate): ~10 min (populate call blocked by plan-tier limit — see Pipeline gaps)
- MemPalace drawers + KG triples (Phase 8 — 9 drawers + 8 triples): ~12 min
- Lessons-learned doc (this file): ~8 min
- **Total:** ~115 min (~1h 55m), within the 2-3 hour per-chapter target.

## Pipeline gaps surfaced

1. **Native Explore subagent dispatch tool not present in current tool registry.** The protocol (`chapter-workflow.md` Phase 4 + `adversarial-reviewer.md`) calls for `Agent tool with subagent_type=Explore`, but in this Opus session the deferred-tool registry does not surface a Task / Agent / Explore handle. The adversarial review was self-administered with independence discipline (re-read source paragraph-by-paragraph as the primary input, treated Stage 1 emission notes as out-of-context, walked the 5 checks in order). This works but loses the "independent context" property of a true subagent — a real review subagent has no chance of overhearing internal extractor reasoning, whereas a self-administered review must work hard to bracket it. Real risk: confirmation bias slipping through Check 1 (missed nodes) and Check 4 (voice drift). Suggested protocol amendment: explicitly document a "self-administered" fallback path with extra discipline rules (e.g., write Stage 1 to disk → start fresh review pass → never re-read draft notes during review).

2. **MemPalace `add_drawer` MCP signature does not accept `tags` as a separate parameter.** The convention doc (`protocols/mempalace-convention.md`) says "every drawer carries a required `artifact_id:<id>` tag" and lists chapter id / node type / status as tags. But the MCP tool signature only accepts `wing`, `room`, `content`, `source_file`, `added_by`. There is no tags parameter. The first-line-of-body convention (`artifact_id: <id> — <title>`) is fully supported and was applied; tags were embedded as a second line of body content (`tags: [...]`) for grep-ability but they are not first-class drawer metadata. Suggested amendment: update `mempalace-convention.md` to either (a) drop the "tags" requirement and rely on body-first-line + body-second-line tag stub for retrieval, or (b) clarify that `mempalace_search` with tag-style queries works against body text rather than separate metadata. (Best test: try `mempalace_search` for `artifact_id:P-00-01` and confirm it finds the drawer — that confirms the body-embedded approach works for retrieval.)

3. **Figma Starter-plan tool-call limit blocks canvas population.** The FigJam file for ch.0 was created successfully (URL recorded), but the populate call (which would render state-spine + principles + anti-patterns + scenarios + footer) was rate-limit-blocked by the Starter plan. The structural map is fully described in `chapters/00-intro.md` and reproducible from that, but the visual canvas is currently empty. This is a downstream cost issue, not a pipeline bug — but if the same limit hits at ch.1, the validator handoff (Phase 8 — Roma + Maks review via canvas) blocks. Suggested action: upgrade plan tier OR write a one-shot populate script that runs in a single MCP call OR populate by hand directly in Figma when plan refreshes.

4. **No `--limit` or `--head` flag on `mempalace_list_drawers` filter for the room's whole content.** Used `limit:10` and got 1 result (`_room_README` only) before adding ch.0 drawers. After Phase 8 added 9 more, did not run a verification list. Should add a Phase 6 step: after Phase 8 MemPalace population, run `mempalace_list_drawers wing=pivot_salepoint room=kai_coach_kb limit=50` and confirm count = (1 readme + N artifacts). Currently this is implicit; should be explicit.

## Protocol amendments needed

Concrete amendments, listed for application (separate commits per `chapter-workflow.md` Step 12 of Task 11):

- **`protocols/adversarial-reviewer.md`**: add an "Operator mode" section near top stating: "Primary path = dispatch via Explore subagent. Fallback path = self-administer with the discipline rules below." Discipline rules: (a) re-read source as primary input, draft as artifact-under-test; (b) walk 5 checks in order, do not loop back to Stage 1 notes during the review; (c) record the mode used in the flag log so reviewers can weight reliability.

- **`protocols/chapter-workflow.md` Phase 8**: add an explicit verification step after MemPalace population: "Run `mempalace_list_drawers wing=pivot_salepoint room=kai_coach_kb limit=100` and confirm count matches (existing + this chapter's node count). Run `mempalace_kg_stats` and confirm triple-count grew by (this chapter's edge count)."

- **`protocols/mempalace-convention.md`**: clarify that the `tags:` line lives inside the body (second line after the first-line artifact id), because `add_drawer` does not accept tags as a separate metadata parameter. Optionally add a "Retrieval verification" subsection demonstrating that `mempalace_search "artifact_id:P-00-01"` returns the right drawer.

- **`protocols/chapter-workflow.md` Phase 7**: add a "Plan-tier note" — Figma Starter plan limits MCP tool calls per session. Plan to run canvas population as a single use_figma call (one script that creates all shapes + connectors + text) rather than incremental calls. The ch.0 attempt was structured this way; the failure was the file-creation call counting against quota separately and the populate exceeding the limit.

- **`templates/_chapter.md`**: no template changes needed. The exemplar entries proved sufficient for ch.0; every required field had a place to land.

- **`voice/kai-voice-persona.md`**: no changes; the persona handled every drafting situation. The "ambiguous we" case (recorded in blind-spot register) is a drafter-discipline issue, not a persona-spec gap.

## Surprises

1. **The intro's principle density is higher than the loop density by a wide margin.** Predicted: principles dominate, loops sparse. Actual: 4 principles, 3 anti-patterns, 2 states, **zero loops**, zero scripts. The dry-run validated the prediction but the *complete* absence of loops in a chapter is itself notable — it means the chapter-workflow Phase 4 adversarial reviewer cannot apply the "loops should have triggers in + transitions out" coverage check at all for ch.0. The Phase 6 schema validator currently flags loops with no edges; it should also handle the no-loops case gracefully (it did, in practice, because there is nothing to flag — but the rule should be explicit).

2. **The intro contains an implicit forward-reference to a commitment loop.** S-luck-seeker → S-skill-committed is structurally a transition, and intuitively there's a "decision loop" that produces it. But the intro does not actually describe that loop (Worre describes his own one-time pivot, but it's not a repeatable cycle). The right place for this loop is ch.1 or ch.2. The chapter file records this as a cross-chapter forward reference with placeholder `L-XX-YY` ids; that read clean and was correctly handled by Stage 2 (no gap-list entries got forced into the "forward-reference" tag for paragraphs that should have been emitted).

3. **The "treat it like a business" principle (P-00-04) wanted to be operational onboarding content but is, in source, a posture principle.** I caught myself initially trying to write a kai_voice_draft that prescribed onboarding actions ("here's the calendar you should set up..."). That would have been an unfaithful paraphrase — source para.7 is about Worre's lack-of-posture, not about which calendar items he should have used. Rewrote the draft to stay at the posture level. This is a small example of paraphrase drift caught by the IP-clean rule's "could this sentence appear word-for-word in the book? if yes, rewrite" test working in reverse — "could this sentence appear word-for-word in a book that doesn't exist yet?" If yes, the paraphrase is overreaching.

4. **The `pdftoppm` dependency missing from `Read` PDF support, BUT `pdftotext` available via mingw.** The official `Read` tool failed to read the PDF directly. Worked around with `pdftotext -layout -f X -l Y` via Bash. This was fine but is a friction point for any extractor without bash access. For ch.1+, document the `pdftotext` workaround in `chapter-workflow.md` Phase 2 so the next extractor doesn't burn 5 minutes diagnosing it.

## Recommendation

**Prep is functionally complete and the pipeline is operationally sound, with two specific carve-outs:**

1. **Apply the 4 protocol amendments listed above** (adversarial-reviewer self-administer path, chapter-workflow MemPalace verification step, mempalace-convention tags-in-body clarification, chapter-workflow Figma plan-tier note). None of these are blockers for ch.1 — they are codifications of working knowledge that emerged from the dry-run. Each is a small Edit. Recommend doing them as separate commits per the plan's Step 12.

2. **Resolve the Figma plan-tier issue before ch.1 validator handoff.** The canvas is the validator interface; if Roma and Maks need it to do their pass, an empty canvas is a blocker for Phase 8. Either upgrade the plan, or accept that ch.1 will hand off to validators via chapter markdown + flag log only.

3. **Restore native Explore subagent dispatch.** If the Task/Agent tool can be made available in future sessions, the adversarial review's independence guarantee strengthens. The self-administered fallback works but should not become the default.

**Recommend declaring prep complete and proceeding to ch.1** once the four protocol amendments are committed and a decision on Figma plan tier is made. The extraction protocol itself is validated by ch.0 — it works end-to-end, produces a coherent artifact, surfaces real anti-patterns (lottery-ticket / blame-externalisation / angle-seeking) that map directly onto the operational worry list Dmitry has flagged from KOL Report findings (zero-downline operators, stalled mid-rank operators, scarcity-panic users).

---

## 2026-06-10 — Proper independent adversarial pass (closes self-administered gap)

The original 2026-06-09 dry-run adversarial review was self-administered (Pipeline gap #1 above). After Dmitry's #2 ruling (2026-06-09, main-session orchestration), ch.0 was eligible for a proper controller-orchestrated review. Run on 2026-06-10 alongside the Terry handoff sync work.

**Run output:** `protocols/adversarial-flags-ch.00.md` — 4 flags, all resolved.

**Flag dispositions:**

- **Flag 1 (Check 1, para.4 "natural mental filters"):** `resolved-deliberate` — Dmitry ratified that the existing `anecdote` tag stands. Paragraph is illustrative content, not a missed node.
- **Flag 2 (Check 2, S-skill-committed body drift):** `resolved-fix` via body softening. The "seven skills" enumeration in the body drew from content outside the intro's source-page range (chs.1-7 of the book describe each skill in turn). Broadening `source_ref` would have required citing outside pp.9-11, which violates per-chapter source scope. Body softened to align with what's actually in para.15.
- **Flag 3 (Check 2, P-00-01 source_ref drift):** `resolved-fix` via source_ref broadening. Body claims drew from para.13 + para.14; original `source_ref` cited para.14 only. New snippet co-cites both, 20 words (under 30-word cap).
- **Flag 4 (Check 2, P-00-03 source_ref drift):** `resolved-fix` via source_ref broadening. Body's blame-target enumeration drew from para.8; original `source_ref` cited para.12 only. New snippet co-cites both, 24 words (under 30-word cap).

**No structural changes:** zero new nodes, zero new edges, zero ontology changes. All fixes are citation-precision (source_ref broadening) or wording-precision (body softening to match cited source). Voice register, anti-pattern symmetry, gap-list — all clean on the independent pass.

**Reviewer's no-flag observations:**
- AP-00-01, AP-00-02, AP-00-03 all have both required edges (`corrects` from principle, `vulnerable_to` from `S-luck-seeker`). No unreachable anti-pattern.
- Voice register clean across all 9 nodes — zero negative-list violations. Prior `resolved-fix` on `S-luck-seeker` (ambiguous "we" from the original dry-run) holds.
- Carry-through states (`S-luck-seeker`, `S-skill-committed`) re-used in ch.1 consistently with ch.0 definitions.

**What this confirms about the original dry-run:** ontology + voice + coverage held up under proper independent review. The only weakness was source-citation precision (Check 2) — exactly the class of error a self-administered reviewer would underweight (the extractor knows what they meant, so cites the most salient paragraph; an independent reviewer notices when other paragraphs also contributed). This is now a documented blind-spot class — adding to `project_kai_blind_spot_register.md`: "self-administered Check 2 underweighting" — applies retroactively to any chapter reviewed without an independent pass.
