| |
| """ |
| Commitment Conservation Demo — Interactive Falsification Instrument |
| |
| Paste your text. See your commitments extracted. Watch baseline collapse |
| while enforcement holds. Run your own falsification. |
| |
| This is not a showcase. This is a measurement instrument. |
| """ |
| import os |
| os.environ.setdefault('MPLBACKEND', 'Agg') |
|
|
| import sys |
| sys.path.insert(0, os.path.dirname(__file__)) |
|
|
| import json |
| import gradio as gr |
| import matplotlib |
| matplotlib.use('Agg') |
| import matplotlib.pyplot as plt |
|
|
| from src.extraction import extract_commitments, extract_commitment_texts |
| from src.fidelity import fidelity_breakdown |
| from src.compression import get_backend |
| from src.runner import run_recursion |
| from src.lineage import check_attractor_collapse |
|
|
|
|
| def extract_and_display(text): |
| """Extract commitments and display them with type classification.""" |
| if not text.strip(): |
| return "⚠️ Enter text to analyze.", "" |
| |
| commitments = extract_commitments(text) |
| |
| if not commitments: |
| return "**No commitments detected.** Try text with modal operators: *must, shall, cannot, required, always, never*", "" |
| |
| |
| lines = [f"### {len(commitments)} Commitment{'s' if len(commitments) != 1 else ''} Found\n"] |
| for i, c in enumerate(commitments, 1): |
| icon = {'obligation': '📋', 'prohibition': '🚫', 'constraint': '⚡'}.get(c.modal_type, '•') |
| cond = " *(conditional)*" if c.is_conditional else "" |
| lines.append(f"{icon} **{c.modal_type.title()}** `{c.modal_operator}`: {c.text}{cond}") |
| |
| |
| canonical = extract_commitment_texts(text) |
| canon_display = "**Canonical forms** (used for fidelity scoring):\n" |
| for ct in sorted(canonical): |
| canon_display += f"- `{ct}`\n" |
| |
| return "\n\n".join(lines), canon_display |
|
|
|
|
| def run_comparison(text, num_iterations, drift_rate): |
| """Run baseline vs enforced comparison.""" |
| if not text.strip(): |
| return "⚠️ Enter text first.", None, None, None |
| |
| commitments = extract_commitment_texts(text) |
| if not commitments: |
| return "⚠️ No commitments found. Cannot run comparison.", None, None, None |
| |
| |
| baseline_backend = get_backend('lossy', drift_rate=drift_rate) |
| enforced_backend = get_backend('lossy_enforced', drift_rate=drift_rate) |
| |
| |
| baseline_chain = run_recursion( |
| text, baseline_backend, depth=num_iterations, |
| enforce=False, threshold=0.6, target_ratio=0.5, |
| ) |
| |
| |
| enforced_backend.reset() |
| enforced_chain = run_recursion( |
| text, enforced_backend, depth=num_iterations, |
| enforce=True, threshold=0.6, target_ratio=0.5, |
| ) |
| |
| |
| b_fidelities = [1.0] + baseline_chain.fidelity_curve |
| e_fidelities = [1.0] + enforced_chain.fidelity_curve |
| iterations = list(range(num_iterations + 1)) |
| |
| |
| fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5)) |
| |
| |
| ax1.plot(iterations, b_fidelities, 'o-', label='Baseline (no enforcement)', |
| color='#dc2626', linewidth=2.5, markersize=7) |
| ax1.plot(iterations, e_fidelities, 's-', label='Enforced (commitment gate)', |
| color='#16a34a', linewidth=2.5, markersize=7) |
| ax1.axhline(y=0.6, linestyle='--', color='#9ca3af', alpha=0.6, label='Threshold (0.6)') |
| ax1.fill_between(iterations, b_fidelities, e_fidelities, alpha=0.15, color='#16a34a') |
| ax1.set_xlabel('Iteration', fontsize=12) |
| ax1.set_ylabel('Min-Aggregated Fidelity', fontsize=12) |
| ax1.set_title('Commitment Fidelity Over Recursive Compression', fontsize=13, fontweight='bold') |
| ax1.legend(fontsize=10, loc='lower left') |
| ax1.grid(True, alpha=0.2) |
| ax1.set_ylim([-0.05, 1.05]) |
| ax1.set_xlim([0, num_iterations]) |
| |
| |
| b_drifts = [1.0 - f for f in b_fidelities] |
| e_drifts = [1.0 - f for f in e_fidelities] |
| ax2.plot(iterations, b_drifts, 'o-', label='Baseline drift', |
| color='#dc2626', linewidth=2.5, markersize=7) |
| ax2.plot(iterations, e_drifts, 's-', label='Enforced drift', |
| color='#16a34a', linewidth=2.5, markersize=7) |
| ax2.fill_between(iterations, e_drifts, b_drifts, alpha=0.15, color='#dc2626') |
| ax2.set_xlabel('Iteration', fontsize=12) |
| ax2.set_ylabel('Semantic Drift (1 - Fidelity)', fontsize=12) |
| ax2.set_title('Commitment Drift Accumulation', fontsize=13, fontweight='bold') |
| ax2.legend(fontsize=10, loc='upper left') |
| ax2.grid(True, alpha=0.2) |
| ax2.set_ylim([-0.05, 1.05]) |
| ax2.set_xlim([0, num_iterations]) |
| |
| plt.tight_layout() |
| |
| |
| trace_lines = ["### Text At Each Iteration\n"] |
| trace_lines.append("**Original:**\n") |
| trace_lines.append(f"> {text}\n") |
| |
| for i, (b_rec, e_rec) in enumerate(zip(baseline_chain.records, enforced_chain.records)): |
| trace_lines.append(f"\n**Iteration {i+1}:**") |
| trace_lines.append(f"- 🔴 Baseline: `{b_rec.text_preview}`") |
| b_detail = b_rec.fidelity_detail |
| trace_lines.append(f" Fidelity: {b_rec.fidelity:.3f} (J={b_detail.get('jaccard', 0):.2f} C={b_detail.get('cosine', 0):.2f} N={b_detail.get('nli_proxy', 0):.2f})") |
| trace_lines.append(f"- 🟢 Enforced: `{e_rec.text_preview}`") |
| e_detail = e_rec.fidelity_detail |
| trace_lines.append(f" Fidelity: {e_rec.fidelity:.3f} (J={e_detail.get('jaccard', 0):.2f} C={e_detail.get('cosine', 0):.2f} N={e_detail.get('nli_proxy', 0):.2f})") |
| |
| |
| final_b = baseline_chain.final_fidelity |
| final_e = enforced_chain.final_fidelity |
| gap = final_e - final_b |
| |
| summary = f"""## Results |
| |
| | | Baseline | Enforced | Gap | |
| |---|---|---|---| |
| | **Final Fidelity** | {final_b:.3f} | {final_e:.3f} | **+{gap:.3f}** | |
| | **Commitments Surviving** | {baseline_chain.records[-1].commitments_found}/{len(commitments)} | {enforced_chain.records[-1].commitments_found}/{len(commitments)} | | |
| | **Collapse Detected** | {'⚠️ Yes' if baseline_chain.collapse_detected else 'No'} | {'⚠️ Yes' if enforced_chain.collapse_detected else 'No'} | | |
| |
| {'✅ **Conservation law validated**: enforcement preserves commitments that baseline destroys.' if gap > 0.1 else '⚠️ Gap is small — try more iterations or higher drift rate.'} |
| |
| *Scoring: min(Jaccard, Cosine, NLI proxy) — all three must pass.* |
| """ |
| |
| return summary, fig, "\n".join(trace_lines), json.dumps({ |
| 'baseline': baseline_chain.to_dict(), |
| 'enforced': enforced_chain.to_dict(), |
| }, indent=2) |
|
|
|
|
| |
| |
| |
|
|
| DEMOS = { |
| "Contract (payment + penalty)": "You must pay $100 by Friday if the deal closes. The weather forecast suggests rain, so plan accordingly. Late payments will incur a 5% penalty.", |
| "Lease (prohibition + obligation)": "The tenant shall not sublet the premises without written consent from the landlord. The building was constructed in 1952 and features original hardwood floors. You must provide 30 days written notice before vacating.", |
| "Security (requirements + prohibition)": "All passwords must be at least 12 characters long and shall include at least one special character. The user interface was recently redesigned for better accessibility. Passwords must not contain the username or common dictionary words.", |
| "Composite (4 commitments)": "The system must encrypt all data at rest using AES-256 or stronger. Our cloud provider offers competitive pricing. Data in transit shall be protected with TLS 1.3. You must not store encryption keys alongside encrypted data. Annual security audits are required for all systems handling sensitive information.", |
| "Medical (obligations + prohibition)": "Patients must fast for 12 hours before the blood draw. The clinic has recently upgraded its diagnostic equipment. Results shall be communicated to the patient within 5 business days. You must not discontinue prescribed medications without consulting your physician.", |
| } |
|
|
|
|
| |
| |
| |
|
|
| with gr.Blocks( |
| title="⚖️ Commitment Conservation Harness", |
| ) as demo: |
| |
| gr.Markdown(""" |
| # ⚖️ Commitment Conservation — Falsification Instrument |
| |
| **Paste text with commitments. Watch what survives recursive compression.** |
| |
| Baseline systems lose commitments through modal softening, quantity erosion, and conversational drift. |
| Enforcement systems preserve them. This instrument measures the gap. |
| |
| 📄 *A Conservation Law for Commitment in Language Under Transformative Compression and Recursive Application* — D.J.M., Ello Cello LLC |
| """) |
| |
| with gr.Row(): |
| with gr.Column(scale=2): |
| signal_input = gr.Textbox( |
| label="Input Signal", |
| placeholder="Enter text containing commitments (must, shall, cannot, required, always, never)...", |
| lines=5, |
| value=DEMOS["Contract (payment + penalty)"] |
| ) |
| |
| preset_dropdown = gr.Dropdown( |
| choices=list(DEMOS.keys()), |
| label="Or select a preset:", |
| value="Contract (payment + penalty)" |
| ) |
| |
| with gr.Row(): |
| iterations_slider = gr.Slider( |
| minimum=3, maximum=10, step=1, value=10, |
| label="Iterations" |
| ) |
| drift_slider = gr.Slider( |
| minimum=0.1, maximum=0.8, step=0.1, value=0.4, |
| label="Drift Rate (simulated LLM noise)" |
| ) |
| |
| extract_btn = gr.Button("🔍 Extract Commitments", variant="secondary") |
| run_btn = gr.Button("🔬 Run Falsification Protocol", variant="primary", size="lg") |
| |
| with gr.Column(scale=1): |
| commitments_display = gr.Markdown(label="Extracted Commitments") |
| canonical_display = gr.Markdown(label="Canonical Forms") |
| |
| summary_display = gr.Markdown(label="Results") |
| results_plot = gr.Plot(label="Fidelity Curves") |
| |
| with gr.Accordion("📝 Text Trace (what happens at each iteration)", open=False): |
| trace_display = gr.Markdown() |
| |
| with gr.Accordion("📊 Raw JSON (lineage chains)", open=False): |
| json_display = gr.Code(language="json", label="Protocol Receipt") |
| |
| gr.Markdown(""" |
| --- |
| ### How It Works |
| |
| 1. **Extract**: Modal-pattern sieve identifies commitments (obligations, prohibitions, constraints) |
| 2. **Compress**: Text is recursively compressed through a lossy channel simulating LLM behavior |
| 3. **Measure**: Fidelity scored as min(Jaccard, Cosine, NLI) — all three must pass |
| 4. **Compare**: Baseline (no awareness) vs Enforced (commitment-preserving selection) |
| |
| The **lossy backend** simulates real LLM drift: modal softening (*must → should → maybe*), |
| quantity erosion (*$100 → "the amount"*), and sentence dropping. Deterministic and seeded |
| for reproducibility. For results with real models, run the harness locally with `--backend bart`. |
| |
| **This is a measurement instrument, not a product demo.** Paste your own contracts, |
| API specs, medical protocols, legal clauses — anything with commitments — and see |
| whether they survive. |
| |
| --- |
| ⚖️ MO§ES™ is a trademark of Ello Cello LLC. © 2026 Ello Cello LLC. All rights reserved. |
| """) |
| |
| |
| preset_dropdown.change( |
| fn=lambda name: DEMOS[name], |
| inputs=[preset_dropdown], |
| outputs=[signal_input] |
| ) |
| |
| extract_btn.click( |
| fn=extract_and_display, |
| inputs=[signal_input], |
| outputs=[commitments_display, canonical_display] |
| ) |
| |
| run_btn.click( |
| fn=extract_and_display, |
| inputs=[signal_input], |
| outputs=[commitments_display, canonical_display] |
| ).then( |
| fn=run_comparison, |
| inputs=[signal_input, iterations_slider, drift_slider], |
| outputs=[summary_display, results_plot, trace_display, json_display] |
| ) |
|
|
|
|
| if __name__ == "__main__": |
| demo.launch() |
|
|