core/generate
Shay 30948a1605 feat(runtime): wire discourse planner behind RuntimeConfig flag
Step 5 of the discourse-planner sequencing.  Closes the chain:

    classify_intent + classify_response_mode
      -> grounding_bundle_for(subject)
      -> plan_discourse(intent, mode, bundle)
      -> render_plan(plan)
      -> response_surface

Adds RuntimeConfig.discourse_planner (default False).  When True, the
runtime — after the warm pack/teaching-grounded surface is set —
classifies the response mode, assembles a GroundingBundle from the
ADR-style accessors, builds a DiscoursePlan, and replaces the warm
surface with the deterministic multi-clause rendering whenever the
plan has more than one move.

Gating discipline:
* Engages only on warm_grounding_source in {"pack", "teaching"} so
  vault/none turns and the discovery-signal CAUSE/VERIFICATION
  disclosure are preserved exactly.
* BRIEF mode always collapses to a single ANCHOR move, so flag-on
  with BRIEF intent is byte-identical to flag-off.
* Empty bundles produce empty plans; the runtime falls through to
  the existing warm surface untouched.

Adds render_plan(plan) to generate/discourse_planner.py — a pure,
deterministic multi-clause renderer with fixed canonical connectives:
  ANCHOR    : capitalized opening sentence
  SUPPORT   : "Furthermore, ..."
  RELATION  : "In turn, ..."
  TRANSITION: "Consequently, ..."
  CLOSURE   : skipped when fact is None
Every visible token is a verbatim pack lexicon entry, gloss, or
reviewed teaching chain string — no synthesis.

13 new tests pin:
* render_plan empty/brief/paragraph shape
* canonical connectives present in paragraph rendering
* deterministic + verbatim-fact invariants
* RuntimeConfig.discourse_planner defaults False
* Flag-off surface has no planner connectives
* Flag-on lifts produce structurally well-formed multi-sentence
  output on grounded substrate

Lift measurement (multi_sentence_response public/v1, 15 cases):
* flag off: multi=0.40, connective=0.50, grounded=0.40
* flag on : multi=0.40, connective=0.60, grounded=0.40
  -> connective_present_rate +10pp; multi-sentence count flat
     because the existing narrative composer's literal "." chars in
     tags like "cognition.truth" already trigger sentence splits in
     the lane regex.  Real lift is form quality: e.g. "Tell me about
     truth" now renders as "Truth is a claim or state grounded by
     evidence and coherent judgment.  Furthermore, truth belongs to
     cognition.truth.  In turn, truth grounds knowledge." instead of
     the prior provenance-laden narrative surface.

Critical gates (all green):
* flag off: cognition eval byte-identical
  - public 100/100/91.7/100, holdout 100/100/83.3/100
* smoke suite 67/67
* conversational_thread_coherence: 3 unwanted placeholders flag off
  and flag on (no regression)
* planner JSON byte-stable across calls (contract tests)
* grounding source order preserved (sidecar tests)
2026-05-19 11:29:25 -07:00
..
__init__.py
admissibility.py feat(adr-0026): Phase 3 — ranked admissibility with margin 2026-05-17 15:03:03 -07:00
articulation.py
attention.py
bridge_trace.py Phase 1 — bridge trace instrumentation (observation-only) 2026-05-18 18:04:57 -07:00
dialogue.py
discourse_planner.py feat(runtime): wire discourse planner behind RuntimeConfig flag 2026-05-19 11:29:25 -07:00
exhaustion.py feat(adr-0025): Phase 4 — rotor / frame admissibility at the seam 2026-05-17 15:16:32 -07:00
graph_constraint.py fix(adr-0046): make forward-graph-constraint branch mergeable 2026-05-18 05:57:46 -07:00
graph_planner.py
grounding_accessors.py feat(grounding): structured GroundedFact accessors for discourse planner 2026-05-19 11:19:59 -07:00
intent.py feat(intent): ResponseMode classifier + sibling to classify_intent 2026-05-19 11:15:32 -07:00
intent_bridge.py Phase 2 — proposition-slot grounding for articulate_with_intent 2026-05-18 18:18:31 -07:00
intent_ratifier.py feat(adr-0022): Forward Semantic Control — Accepted 2026-05-17 12:10:20 -07:00
morphology.py fix(gaps): close G1+G2+G3 + identity vocab + pipeline safety-stub honour 2026-05-16 21:21:06 -07:00
operators.py feat(compositionality): compose_relations operator lifts lane 68.8% → 100% 2026-05-16 22:44:06 -07:00
proposition.py feat(adr-0022): Forward Semantic Control — Accepted 2026-05-17 12:10:20 -07:00
realizer.py feat(benchmarks): discourse_paragraph lane + pipeline profiler + word-selection tracer 2026-05-16 21:53:46 -07:00
render.py
result.py feat(adr-0023): Forward Semantic Control proof evidence — Accepted 2026-05-17 12:55:19 -07:00
rotor_admissibility.py feat(adr-0025): Phase 4 — rotor / frame admissibility at the seam 2026-05-17 15:16:32 -07:00
salience.py
semantic_templates.py
stream.py feat(adr-0025): Phase 4 — rotor / frame admissibility at the seam 2026-05-17 15:16:32 -07:00
surface.py feat(surface): ADR-0031 — score-decomposition surface (per-axis hedges) 2026-05-17 20:16:22 -07:00
templates.py fix(gaps): close G1+G2+G3 + identity vocab + pipeline safety-stub honour 2026-05-16 21:21:06 -07:00