"""cohere.py — COHERE stage: document-level flow, not stitched sentences. Fidelity is REALIZE's job; FLOW is this stage's. The hard part beyond sentence fidelity is that a document must read as one thing. We add connective tissue at the passage level: * an opening abstract that names what the document covers (built ONLY from the section headings that already exist — it introduces no new claim), * a short transition lead into each section after the first, drawn from a fixed set of discourse connectives ("Beyond that,", "Relatedly,", ...) that carry no propositional content, * ordering so the highest-grounded section leads. CRITICAL: every connective is marked ``kind="connective"`` in its provenance, so the faithfulness audit can prove COHERE introduced ZERO new geometry claims. A transition is discourse glue, never a fact. """ from __future__ import annotations from document_ir import Block, DocumentIR, Provenance # discourse connectives — pure flow, no propositional content _TRANSITIONS = [ "Beyond that,", "Relatedly,", "In the same region,", "From there,", "Alongside this,", "Further,", "Turning to the next facet,", ] def _connective_prov() -> Provenance: return Provenance(subj_id=None, subject=None, relation="", obj=None, polarity="aff", confidence=1.0, node_id=None, kind="connective") def _abstract_block(doc: DocumentIR) -> Block: """A grounded opening: names the sections, asserts nothing new.""" headings = [s.heading for s in doc.sections] if not headings: return Block(role="lead") if len(headings) == 1: body = f"This document, generated from Neuron's geometry, covers {headings[0]}." else: listed = ", ".join(headings[:-1]) + f", and {headings[-1]}" body = ("This document is projected directly from Neuron's meaning-geometry. " f"It traces {listed}.") b = Block(role="lead") b.sentences.append(body) b.provenance.append(_connective_prov()) return b def cohere_document(doc: DocumentIR, *, add_abstract: bool = True, add_transitions: bool = True) -> DocumentIR: """Order sections by grounding, add abstract + transitions (flow only).""" # order: strongest-grounded section (mean confidence x #claims) first, # but keep an explicitly-first section if the plan pinned one via level 1. def _score(sec): provs = [p for p in sec.all_provenance() if p.kind == "fact"] if not provs: return 0.0 mean_conf = sum(p.confidence for p in provs) / len(provs) return mean_conf * len(provs) doc.sections.sort(key=_score, reverse=True) if add_transitions: for i, sec in enumerate(doc.sections): if i == 0 or not sec.blocks: continue lead = _TRANSITIONS[(i - 1) % len(_TRANSITIONS)] first = sec.blocks[0] if first.sentences: # prepend the connective to the first sentence (flow, no new claim) first.sentences[0] = f"{lead} {first.sentences[0][0].lower()}{first.sentences[0][1:]}" if add_abstract: doc.meta["abstract"] = _abstract_block(doc) return doc