Repo: motir-core. One PR. The PRODUCER half of a two-repo contract gap; the consumer half is its dependent card.
aiGenerationService.generateTree puts the project's opt-in on the wire — generateExplanations: ctx.project.aiGenerateExplanations in the generate_tree job envelope's context — with a comment stating that motir-ai reads it from context.generateExplanations and never reads core config directly. The re-plan submit path does not send that field at all.
Consequence: a project that has turned AI-drafted explanations ON in /settings/project/ai-planning gets a per-node "why this matters" on a fresh generation, and nothing on a re-plan — the setting reads as global but is silently generation-only. Because the flag rides the envelope by design, motir-ai cannot compensate; if core does not send it, the re-planner cannot know.
Verified on origin/main (2026-08-04): git grep generateExplanations in lib/ returns the settings editor, lib/ai/types.ts, and the generate_tree submit — and no re-plan submit site.
context.generateExplanations from ctx.project.aiGenerateExplanations, exactly as the generate_tree submit does — same field name, same source, no new config path.lib/ai/types.ts) admits the field on the re-plan request shape, and a test asserts the submitted envelope carries it for a project with the setting ON, and the value false (not an omission that reads as "unset") when OFF — match whatever discipline generate_tree already uses for the OFF case.generate_tree.MOTIR-<id>.lib/services/aiGenerationService.ts — the generate_tree submit that DOES send it (the shape to copy) and the re-plan submit that does not.lib/ai/types.ts — the job-envelope context type carrying generateExplanations.app/(authed)/settings/project/ai-planning/_components/AiPlanningSettingsEditor.tsx — the user-facing toggle whose promise is currently half-kept.motir-ai/src/jobs/handlers/replan.ts — the consumer that must then read it (the dependent card).