fsi-anomaly / research /workspace.py
FerrellSyntheticIntelligence's picture
backup all: 100 files (batch)
76b78ee verified
Raw
History Blame Contribute Delete
5.78 kB
"""Research workspace: turn case notes into analytic artifacts (the sandbox).
The tiny head reasons; the workspace materializes. Given a case ledger (NOTE
lines, search hits, verdicts) it renders, saves, and returns markdown documents:
- timeline events with dates, sorted, source-tagged
- evidence claim/evidence/value rows (the discrepancy table)
- series two value series as an ASCII chart (pattern display)
- crossref a theme/symbol mapped to every source that mentions it
Deterministic only - no model inference here. Artifacts are saved under
data/artifacts/ so a case produces durable documents, not just chat.
"""
import json
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
ART_DIR = ROOT / "data" / "artifacts"
DATE_RE = re.compile(r"\b((?:19|20)\d{2}(?:-\d{1,2}(?:-\d{1,2})?)?)\b")
VALUE_RE = re.compile(r"\b(\d{1,2}:\d{2}|\d+(?:,\d{3})*\.?\d*%?)\b")
SOURCE_RE = re.compile(r"\[([a-z0-9_./-]+)\]|(https?://\S+)")
ART_KINDS = ("timeline", "evidence", "series", "crossref")
def _slug(s):
return re.sub(r"[^a-z0-9]+", "_", s.lower()).strip("_") or "artifact"
def save_md(title, md):
ART_DIR.mkdir(parents=True, exist_ok=True)
path = ART_DIR / f"{_slug(title)}.md"
path.write_text(md + ("\n" if not md.endswith("\n") else ""), encoding="utf-8")
return path
def _src(line):
m = SOURCE_RE.search(line)
return m.group(1) or m.group(2) if m else "-"
def split_rows(ledger):
"""Split a ledger into (date_rows, value_rows, bare_rows)."""
dates, values, bare = [], [], []
for ln in ledger:
ln = ln.strip()
if not ln:
continue
dm = DATE_RE.search(ln)
if dm:
dates.append((dm.group(1), ln, _src(ln)))
continue
vm = VALUE_RE.search(ln)
if vm:
values.append((ln, _src(ln)))
else:
bare.append(ln)
dates.sort(key=lambda r: r[0])
return dates, values, bare
def render_timeline(ledger, title="Timeline"):
rows, _, _ = split_rows(ledger)
if not rows:
return None
out = [f"# {title}", "", "| Date | Event | Source |", "|---|---|---|"]
for d, ln, s in rows:
out.append(f"| {d} | {ln[:140]} | {s} |")
out.append("")
out.append("_Ordering is verifiable only where the source records the date; "
"gaps are as informative as entries._")
return "\n".join(out)
def render_evidence(ledger, title="Evidence & Discrepancies"):
rows, _, _ = split_rows(ledger)
if not rows:
return None
out = [f"# {title}", "", "| Date | Statement | Source |", "|---|---|---|"]
for d, ln, s in rows:
out.append(f"| {d} | {ln[:140]} | {s} |")
return "\n".join(out)
def render_series(series, title="Series Comparison"):
"""series: list of (label, [numbers]). ASCII bars side by side."""
if not series or len(series) < 2:
return None
labels = [s[0] for s in series]
seqs = [list(s[1]) for s in series]
n = min(len(x) for x in seqs)
if n == 0:
return None
out = [f"# {title}", "", f"| {' | '.join(labels)} |", f"|{'---|' * len(labels)}"]
for i in range(n):
vals = [x[i] for x in seqs]
out.append("| " + " | ".join(f"{v:.4g}" for v in vals) + " |")
out.append("")
out.append("Points (index) " + " ".join(f"[{i}]" for i in range(n)))
for j, (lab, seq) in enumerate(series):
mx = max(seq) or 1
bars = ["#" * max(1, round(v / mx * 20)) for v in seq]
out.append(f"{lab}: " + " ".join(bars))
out.append("")
out.append("_The chart only compares values; it asserts nothing about cause._")
return "\n".join(out)
def render_crossref(theme, lines, title="Cross-Reference"):
"""theme: a term/symbol; lines: source-tagged ledger/notes."""
out = [f"# {title}", "", f"Theme/symbol: **{theme}**", "", "| Source | Context |", "|---|---|"]
hit = 0
low = theme.lower()
for ln in lines:
if low in ln.lower():
out.append(f"| {_src(ln)} | {ln[:150]} |")
hit += 1
if not hit:
out.append("| - | (no mention in this case's documents) |")
out.append("")
out.append("_Absence of a mention is a finding, not an error: note it explicitly._")
return "\n".join(out)
def synthesize(ledger, title, series=None, theme=None, lines=None):
"""Compose every artifact available for a case into one saved document."""
arts = []
tl = render_timeline(ledger, title=f"{title} - Timeline")
if tl:
arts.append(tl)
ev = render_evidence(ledger, title=f"{title} - Evidence & Discrepancies")
if ev:
arts.append(ev)
ch = render_series(series, title=f"{title} - Series Comparison") if series else None
if ch:
arts.append(ch)
cr = render_crossref(theme, lines or ledger, title=f"{title} - Cross-Reference") if theme else None
if cr:
arts.append(cr)
if not arts:
return None
doc = "\n\n---\n\n".join(arts)
ART_DIR.mkdir(parents=True, exist_ok=True)
path = ART_DIR / f"{_slug(title)}.md"
path.write_text(doc + "\n", encoding="utf-8")
return str(path), doc
def parse_series_arg(arg):
"""'title | label1:1,2,3 | label2:4,5,6' -> (title, [(label, [nums])])."""
parts = [p.strip() for p in arg.split("|")]
title = parts[0] or "Series Comparison"
series = []
for p in parts[1:]:
if ":" not in p:
continue
lab, vs = p.split(":", 1)
nums = []
for v in vs.replace(" ", "").split(","):
try:
nums.append(float(v))
except ValueError:
pass
if nums:
series.append((lab.strip(), nums))
return title, series