4bbfdcceff
audio-surface.el / image-surface.el: own-core additive-synthesis WAV and
raster-PNG renderers (integer-only DSP, since EL has no floats), rendered
from learned engram signatures via a pluggable surface-profile
abstraction (surface-profile.el). audio-demo.el / image-demo.el are
drivers. NOTE: demo files hardcode absolute paths to this worktree's own
directory — will need a path fixup before landing.
elp/projector/ is a Python package the author's own README marks as
"STAGING/PROOF-OF-SHAPE — not the deliverable", superseded by the native
.el surface-profile work above; kept as a validated architecture proof.
Generated output (elp/faculty/{out,sig}, elp/projector/out,
__pycache__) intentionally excluded.
193 lines
7.5 KiB
Python
193 lines
7.5 KiB
Python
"""plan.py — PLAN stage: geometry region -> document skeleton (a DAG/outline).
|
||
|
||
The manifold becomes the skeleton. We extract faithful propositions from the
|
||
region's nodes (the proven neuron-talk extractor, SACRED polarity preserved),
|
||
apply a quality floor, then GROUP them into sections. Grouping is by source
|
||
node — each engram node is one coherent topic, so one salient node becomes one
|
||
section. The section ORDER is the node ranking (importance/salience): the
|
||
geometry decides the outline, not a template.
|
||
|
||
Output: a DocumentIR whose sections carry seed node ids and empty blocks. REALIZE
|
||
fills the blocks; the plan owns the structure.
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import os
|
||
import re
|
||
import sys
|
||
|
||
_NT = os.path.expanduser("~/Desktop/neuron-talk")
|
||
_LR = os.path.expanduser("~/Desktop/lang-realizers")
|
||
for _p in (_NT, _LR):
|
||
if _p not in sys.path:
|
||
sys.path.insert(0, _p)
|
||
|
||
import propositions # noqa: E402 (the proven, faithful extractor)
|
||
|
||
from document_ir import DocumentIR, Section # noqa: E402
|
||
from geometry import Region # noqa: E402
|
||
|
||
|
||
# --------------------------------------------------------------------------- #
|
||
# Proposition quality — keep only clean, well-grounded claims.
|
||
# --------------------------------------------------------------------------- #
|
||
_JUNK_RE = re.compile(r"[.][a-z]{1,3}\b|[^A-Za-z0-9 '\-]") # ".o", stray symbols
|
||
|
||
|
||
def _has_banner_token(s: str) -> bool:
|
||
"""True if any word is an ALLCAPS banner token (DHARMA, ENGRAM, MEASURED)."""
|
||
for w in (s or "").split():
|
||
core = w.strip(".,:;'\"-")
|
||
if len(core) > 2 and core.isupper():
|
||
return True
|
||
return False
|
||
|
||
|
||
def _clean_prop(p, floor: float) -> bool:
|
||
if p.confidence < floor:
|
||
return False
|
||
if not p.subject or not (p.object or (p.obj_np is not None)):
|
||
return False
|
||
subj = (p.subject or "").strip()
|
||
obj = (p.object or "").strip()
|
||
if len(subj) < 2:
|
||
return False
|
||
# banner-derived shouty fragments read as garbage in prose
|
||
if _has_banner_token(subj) or _has_banner_token(obj):
|
||
return False
|
||
if propositions._is_shouty(p.sentence or ""):
|
||
return False
|
||
# junk tokens: file-extension fragments (".o"), stray non-word symbols
|
||
if _JUNK_RE.search(subj) or _JUNK_RE.search(obj):
|
||
return False
|
||
# a proposition whose object repeats the subject is usually a parse artifact
|
||
if obj and subj.lower() == obj.lower():
|
||
return False
|
||
# a bare copula with no real complement ("X is it") reads as noise
|
||
if p.predicate == "be" and obj.lower() in ("it", "no", "nothing", "empty", ""):
|
||
return False
|
||
return True
|
||
|
||
|
||
def _dedup(props):
|
||
"""Drop duplicate claims. Two axes: (a) identical (pred,obj,polarity), and
|
||
(b) same (subject,predicate) — which collapses a mis-split compound like
|
||
"detection is post-hoc eval" -> "Detection is post/hoc/eval" into one claim
|
||
(keep the highest-confidence surface)."""
|
||
props = sorted(props, key=lambda p: p.confidence, reverse=True)
|
||
seen_po, seen_sp, out = set(), set(), []
|
||
for p in props:
|
||
subj = (p.subject or "").lower()
|
||
po = (p.predicate, (p.object or "").lower(), p.polarity)
|
||
sp = (subj, p.predicate, p.polarity)
|
||
if po in seen_po or sp in seen_sp:
|
||
continue
|
||
seen_po.add(po)
|
||
seen_sp.add(sp)
|
||
out.append(p)
|
||
return out
|
||
|
||
|
||
# --------------------------------------------------------------------------- #
|
||
# Heading derivation — a clean human heading from a node.
|
||
# --------------------------------------------------------------------------- #
|
||
_HEADING_RE = re.compile(r"^\s*#{1,4}\s+(.{2,70})\s*$", re.M)
|
||
# node-type / system labels that are NOT topical headings
|
||
_NONTOPIC_LABEL = re.compile(r"^(memory|node|knowledge|doc|session)[:/]", re.I)
|
||
|
||
|
||
def _titlecase_banner(s: str) -> str:
|
||
"""A shouty banner ("CHRONOCEPTION — SCALE-INVARIANCE") makes a fine title
|
||
once Title-cased. Keep short acronyms uppercase."""
|
||
def fix(w):
|
||
core = w.strip("—-:,.")
|
||
if len(core) <= 3 and core.isupper():
|
||
return w # acronym
|
||
return w.capitalize()
|
||
return " ".join(fix(w) for w in s.split())
|
||
|
||
|
||
def _clean_heading(text: str) -> str | None:
|
||
"""First line only, no markdown, capped, banner Title-cased. None if unusable."""
|
||
if not text:
|
||
return None
|
||
line = text.strip().splitlines()[0]
|
||
line = re.sub(r"^#+\s*", "", line).strip().strip("#").strip()
|
||
# cut at a natural break so a long banner heading stays a heading, not a para
|
||
for sep in (" — ", " – ", ": ", ". "):
|
||
if sep in line and len(line) > 48:
|
||
line = line.split(sep)[0].strip()
|
||
break
|
||
if not (3 <= len(line) <= 64):
|
||
return None
|
||
if propositions._is_shouty(line):
|
||
line = _titlecase_banner(line)
|
||
return line or None
|
||
|
||
|
||
def _heading_for(node: dict, fallback: str) -> str:
|
||
label = (node.get("label") or "").strip()
|
||
content = node.get("content") or ""
|
||
candidates: list[str] = []
|
||
# a node-type label ("memory:remembered") is never a topic — skip it
|
||
if label and not _NONTOPIC_LABEL.match(label):
|
||
candidates.append(label)
|
||
m = _HEADING_RE.search(content)
|
||
if m:
|
||
candidates.append(m.group(1))
|
||
# the leading banner/first sentence of the content is often the real title
|
||
first = re.split(r"(?<=[.\n])", content.strip(), maxsplit=1)[0] if content.strip() else ""
|
||
candidates.append(first)
|
||
for c in candidates:
|
||
h = _clean_heading(c)
|
||
if h:
|
||
return h
|
||
return fallback
|
||
|
||
|
||
def plan_document(region: Region, *, title: str, subtitle: str = "",
|
||
format_spec: dict | None = None,
|
||
conf_floor: float = 0.55,
|
||
max_sections: int = 8,
|
||
max_claims_per_section: int = 6) -> DocumentIR:
|
||
"""Region -> DocumentIR skeleton. The geometry dictates the outline."""
|
||
format_spec = format_spec or {}
|
||
doc = DocumentIR(title=title, subtitle=subtitle,
|
||
seed_id=region.nodes[0]["id"] if region.nodes else None,
|
||
format_spec=format_spec)
|
||
|
||
made = 0
|
||
seen_headings: set[str] = set()
|
||
for node in region.nodes:
|
||
if made >= max_sections:
|
||
break
|
||
props = propositions.extract(node.get("content") or "",
|
||
node_id=node.get("id"),
|
||
node_importance=float(node.get("importance") or 0.0),
|
||
max_sentences=10)
|
||
props = [p for p in props if _clean_prop(p, conf_floor)]
|
||
props = _dedup(props)
|
||
props.sort(key=lambda p: p.confidence, reverse=True)
|
||
props = props[:max_claims_per_section]
|
||
if not props:
|
||
continue
|
||
heading = _heading_for(node, fallback=f"Region {made + 1}")
|
||
# cross-section dedup: a topic appears once. Distinguish by top claim
|
||
# subject, else drop the collision so the outline stays clean.
|
||
if heading.lower() in seen_headings:
|
||
subj = (props[0].subject or "").strip().title()
|
||
alt = f"{heading}: {subj}" if subj and subj.lower() not in heading.lower() else None
|
||
if alt and alt.lower() not in seen_headings and len(alt) <= 64:
|
||
heading = alt
|
||
else:
|
||
continue
|
||
seen_headings.add(heading.lower())
|
||
sec = Section(heading=heading, level=2, seed_ids=[node["id"]])
|
||
# stash the planned propositions on the section for REALIZE
|
||
sec.__dict__["_planned_props"] = props
|
||
sec.__dict__["_node"] = node
|
||
doc.sections.append(sec)
|
||
made += 1
|
||
|
||
return doc
|