SPB Git

Repository Public

index.html 33.4 KB 419 lines html

1<!doctype html>2<html lang="en">3<head>4<meta charset="utf-8">5<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">6<title>HTR — Human Text Reconstruction · research preview</title>7<meta name="description" content="Research preview from UQO working paper AI-0002: four reconstruction models (HTR Transformers and fine-tuned pretrained backbones) that map LLM-rewritten scientific prose back towards the register of pre-2018 human writing. Outputs are synthetic reconstructions, not evidence of authorship.">8<meta name="color-scheme" content="light dark">9<meta name="theme-color" content="#f6f3ec" media="(prefers-color-scheme: light)">10<meta name="theme-color" content="#0a1120" media="(prefers-color-scheme: dark)">11<link rel="canonical" href="{{URL}}/">12<link rel="icon" href="/static/favicon.svg" type="image/svg+xml">13<link rel="mask-icon" href="/static/favicon.svg" color="#0f1b33">14<link rel="manifest" href="/site.webmanifest">15<meta property="og:type" content="website">16<meta property="og:site_name" content="HTR · Human Text Reconstruction">17<meta property="og:title" content="HTR — Human Text Reconstruction">18<meta property="og:description" content="Map LLM-rewritten scientific prose back towards the register of pre-2018 human writing. Research preview, UQO WP-AI-0002.">19<meta property="og:url" content="{{URL}}/">20<meta property="og:image" content="{{URL}}/og.svg">21<meta property="og:image:type" content="image/svg+xml">22<meta property="og:image:width" content="1200">23<meta property="og:image:height" content="630">24<meta property="og:image:alt" content="HTR wordmark with a rewritten sentence being restored">25<meta name="twitter:card" content="summary_large_image">26<meta name="twitter:title" content="HTR — Human Text Reconstruction">27<meta name="twitter:description" content="Research preview: LLM-rewritten scientific prose → pre-2018 human register. Synthetic reconstructions, honestly labelled.">28<meta name="twitter:image" content="{{URL}}/og.svg">29<link rel="stylesheet" href="/static/app.css?v={{CSS_V}}">30<script src="/static/app.js?v={{JS_V}}" defer></script>31</head>32<body>33<svg class="sprite" aria-hidden="true" focusable="false">34  <symbol id="i-check" viewBox="0 0 24 24"><path d="M5 12.5l4.2 4.2L19 7" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></symbol>35  <symbol id="i-alert" viewBox="0 0 24 24"><path d="M12 3.5l9.5 16.5h-19z" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linejoin="round"/><path d="M12 10v4.5M12 17.3v.2" stroke="currentColor" stroke-width="2.1" stroke-linecap="round"/></symbol>36  <symbol id="i-info" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="1.9"/><path d="M12 11v6M12 7.6v.2" stroke="currentColor" stroke-width="2.1" stroke-linecap="round"/></symbol>37  <symbol id="i-x" viewBox="0 0 24 24"><path d="M6 6l12 12M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></symbol>38  <symbol id="i-copy" viewBox="0 0 24 24"><rect x="8.5" y="8.5" width="11" height="11" rx="2.5" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M15.5 8.5V6.5a2 2 0 0 0-2-2h-7a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h2" fill="none" stroke="currentColor" stroke-width="1.8"/></symbol>39  <symbol id="i-down" viewBox="0 0 24 24"><path d="M12 4v11m0 0l-4.5-4.5M12 15l4.5-4.5M5 19.5h14" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"/></symbol>40  <symbol id="i-link" viewBox="0 0 24 24"><path d="M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/></symbol>41  <symbol id="i-clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M12 7.5V12l3 2" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></symbol>42  <symbol id="i-sun" viewBox="0 0 24 24"><circle cx="12" cy="12" r="4" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.3 5.3l1.4 1.4M17.3 17.3l1.4 1.4M5.3 18.7l1.4-1.4M17.3 6.7l1.4-1.4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></symbol>43  <symbol id="i-moon" viewBox="0 0 24 24"><path d="M19.5 14.5A8 8 0 0 1 9.5 4.5a8 8 0 1 0 10 10z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></symbol>44  <symbol id="i-hash" viewBox="0 0 24 24"><path d="M9 4L7 20M17 4l-2 16M4.5 9h16M3.5 15h16" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></symbol>45  <symbol id="i-quote" viewBox="0 0 24 24"><path d="M9 5H6a2 2 0 0 0-2 2v4h5v6M20 5h-3a2 2 0 0 0-2 2v4h5v6" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></symbol>46  <symbol id="i-not" viewBox="0 0 24 24"><path d="M12 9.5v4.5M12 16.8v.2" stroke="currentColor" stroke-width="2.1" stroke-linecap="round"/><path d="M12 21a9 9 0 1 0 0-18" fill="none" stroke="currentColor" stroke-width="1.8"/></symbol>47  <symbol id="i-arrow" viewBox="0 0 24 24"><path d="M4 12h15m-5-5l5 5-5 5" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"/></symbol>48  <symbol id="logo" viewBox="0 0 40 40"><rect width="40" height="40" rx="10" fill="var(--logo-bg, #0f1b33)"/><path d="M10 13.5h20M10 20h12.5M10 26.5h16" stroke="#f6f3ec" stroke-width="2.6" stroke-linecap="round"/><path d="M27.2 16.6c3 .6 4.6 2.4 4.6 4.6 0 2.5-2.1 4.4-5 4.4" fill="none" stroke="var(--accent, #d9532b)" stroke-width="2.6" stroke-linecap="round"/><path d="M28.6 23.2l-2.8 2.4 2.8 2.4" fill="none" stroke="var(--accent, #d9532b)" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></symbol>49</svg>5051<a class="skip" href="#workbench">Skip to the workbench</a>5253<header class="top" id="top">54  <div class="wrap top-in">55    <a class="brand" href="/" aria-label="HTR home">56      <svg class="brand-mark" aria-hidden="true"><use href="#logo"/></svg>57      <span class="brand-word">HTR</span>58      <span class="brand-sub">Human Text Reconstruction</span>59    </a>60    <nav class="nav" aria-label="Sections">61      <a href="#workbench">Workbench</a>62      <a href="#how">How it works</a>63      <a href="#limits">Limits</a>64      <a href="#model">Models</a>65      <a href="#api">API</a>66      <a href="#research">Research</a>67    </nav>68    <div class="top-actions">69      <button class="icon-btn" id="history-open" type="button" aria-label="Open run history" aria-haspopup="dialog" aria-controls="history"><svg aria-hidden="true"><use href="#i-clock"/></svg><span class="dot" id="history-dot" hidden></span></button>70      <button class="icon-btn" id="theme" type="button" aria-label="Toggle dark mode" title="Theme: system"><svg class="ic-sun" aria-hidden="true"><use href="#i-sun"/></svg><svg class="ic-moon" aria-hidden="true"><use href="#i-moon"/></svg></button>71    </div>72  </div>73</header>7475<main id="main">76  <section class="hero">77    <div class="wrap hero-in">78      <div class="hero-copy">79        <p class="eyebrow"><span class="pill pill-accent"><span class="pulse" aria-hidden="true"></span>Research preview</span><span class="eyebrow-txt">UQO Working Paper AI-0002</span></p>80        <h1>Undo the LLM rewrite.<br><span class="h1-soft">Recover the register of human scientific prose.</span></h1>81        <p class="lede">HTR takes a paragraph that an LLM has rewritten and proposes a reconstruction in the style of science written before 2018 — numbers, citations and equations protected, every deviation flagged.</p>82        <div class="hero-cta">83          <a class="btn btn-primary" href="#workbench">Open the workbench <svg aria-hidden="true"><use href="#i-arrow"/></svg></a>84          <a class="btn btn-quiet" href="#limits">What it is not</a>85        </div>86        <div class="hero-meta" aria-label="What this server runs">87          <span class="chip chip-accent"><span class="chip-k">Default</span><code id="hero-model">{{MODEL}}</code></span>88          <span class="chip"><span class="chip-k">Models</span><b id="hero-count">{{N_MODELS}}</b></span>89          <span class="chip"><span class="chip-k">Compute</span><b id="hero-device">Apple GPU</b></span>90        </div>91      </div>9293      <figure class="demo" id="demo" aria-label="Live example: an LLM rewrite and this server's reconstruction">94        <div class="demo-card demo-in">95          <div class="demo-head"><span class="tag tag-llm">LLM rewrite</span><span class="demo-label" id="demo-label">Biomedicine · methods</span></div>96          <p class="demo-text" id="demo-input"></p>97        </div>98        <div class="demo-arrow" aria-hidden="true"><svg viewBox="0 0 40 40"><circle cx="20" cy="20" r="19" fill="var(--surface)" stroke="var(--line)"/><path d="M20 11v16m0 0l-6-6m6 6l6-6" fill="none" stroke="var(--accent)" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/></svg></div>99        <div class="demo-card demo-out">100          <div class="demo-head"><span class="tag tag-htr">HTR reconstruction</span><button class="demo-toggle" id="demo-toggle" type="button" aria-pressed="false">Show changes</button></div>101          <p class="demo-text" id="demo-output" aria-live="off"><span class="caret" aria-hidden="true"></span></p>102        </div>103        <figcaption id="demo-cap">Real output of this server, computed at start-up with greedy decoding. Synthetic — not the original text.</figcaption>104      </figure>105    </div>106  </section>107108  <section class="section workbench-sec" id="workbench" aria-labelledby="wb-title">109    <div class="wrap">110      <div class="sec-head">111        <p class="kicker">01 · Workbench</p>112        <h2 id="wb-title">Reconstruct a passage</h2>113        <p class="sec-lede">Paste one rewritten paragraph (60–400 words works best), pick a model, run. Nothing is stored on the server; your last ten runs stay in this browser.</p>114      </div>115116      <div class="examples" role="group" aria-label="Load an example">117        <span class="examples-lbl">Try an example</span>118        <div class="examples-list" id="examples"></div>119      </div>120121      <fieldset class="model-pick" id="model-pick">122        <legend><span class="mp-title">Model</span> <span class="muted small" id="mp-hint">the default is highlighted · larger models are slower</span></legend>123        <div class="models" id="models" role="radiogroup" aria-label="Reconstruction model"></div>124        <p class="mp-caveat muted small" id="mp-caveat" hidden><svg aria-hidden="true"><use href="#i-info"/></svg><span></span></p>125        <p class="mp-detector muted small" id="mp-detector"><svg aria-hidden="true"><use href="#i-info"/></svg><span><b>Detector note.</b> The Pangram line on each tile measures one commercial detector's behaviour on a 54-passage sample (Pangram 4.1, input rewrites 46 % flagged). A low AI-likelihood is not evidence of human authorship, and HTR must not be used to evade AI-text detection or for integrity decisions.</span></p>126      </fieldset>127128      <details class="context" id="context">129        <summary><span class="ctx-title">Context</span> <span class="muted" id="ctx-summary">optional · discipline, era, section</span></summary>130        <div class="ctx-body">131          <p class="ctx-note" id="ctx-note" hidden><svg aria-hidden="true"><use href="#i-info"/></svg><span></span></p>132          <fieldset class="seg-group"><legend>Discipline</legend><div class="seg wrap-seg" id="seg-disc"></div></fieldset>133          <fieldset class="seg-group"><legend>Era of the original</legend>134            <div class="seg-row"><div class="seg" id="seg-era"></div>135              <label class="year-lbl">exact year <input id="year" type="number" inputmode="numeric" min="1500" max="2017" placeholder="e.g. 2012"></label></div>136          </fieldset>137          <fieldset class="seg-group"><legend>Section</legend><div class="seg wrap-seg" id="seg-role"></div></fieldset>138        </div>139      </details>140141      <div class="bench">142        <div class="pane pane-in">143          <div class="pane-head">144            <label class="pane-title" for="text">Input <span class="muted">· LLM-rewritten passage</span></label>145            <button class="link-btn" id="clear" type="button">Clear</button>146          </div>147          <textarea id="text" spellcheck="false" autocomplete="off" placeholder="Paste a rewritten scientific paragraph…" aria-describedby="count"></textarea>148          <div class="pane-foot">149            <span class="count" id="count" aria-live="polite">0 / 8 000 characters</span>150            <span class="meter" aria-hidden="true"><span id="meter-fill"></span></span>151          </div>152        </div>153154        <div class="pane pane-out" aria-busy="false" id="pane-out">155          <div class="progress" id="progress" aria-hidden="true"><span></span></div>156          <div class="pane-head">157            <div class="tabs" role="tablist" aria-label="Result views">158              <button role="tab" id="tab-rec" aria-controls="view-rec" aria-selected="true" type="button">Reconstruction</button>159              <button role="tab" id="tab-diff" aria-controls="view-diff" aria-selected="false" tabindex="-1" type="button">Changes <span class="tab-count" id="diff-count"></span></button>160              <button role="tab" id="tab-checks" aria-controls="view-checks" aria-selected="false" tabindex="-1" type="button">Checks <span class="tab-count" id="checks-count"></span></button>161            </div>162          </div>163          <div class="warnings" id="warnings" role="status" hidden></div>164          <div class="views">165            <div class="view" role="tabpanel" id="view-rec" aria-labelledby="tab-rec" tabindex="0">166              <div class="empty" id="empty">167                <svg viewBox="0 0 120 64" aria-hidden="true"><rect x="2" y="6" width="50" height="52" rx="8" fill="none" stroke="currentColor" stroke-opacity=".35"/><path d="M12 20h30M12 30c6-4 12 4 18 0s8-2 12 0M12 40h22" stroke="currentColor" stroke-opacity=".5" stroke-width="2.4" stroke-linecap="round" fill="none"/><path d="M58 32h8m-3-3l3 3-3 3" stroke="var(--accent)" stroke-width="2.2" fill="none" stroke-linecap="round"/><rect x="70" y="6" width="48" height="52" rx="8" fill="none" stroke="currentColor" stroke-opacity=".35"/><path d="M80 20h28M80 30h20M80 40h24" stroke="currentColor" stroke-opacity=".5" stroke-width="2.4" stroke-linecap="round"/></svg>168                <p>The reconstruction will appear here.</p>169                <p class="muted small">Press <kbd id="kbd-mod">⌘</kbd> <kbd>Enter</kbd> to run.</p>170              </div>171              <div class="skeleton" id="skeleton" hidden><span></span><span></span><span></span><span></span><span></span></div>172              <div class="result-text" id="out" hidden></div>173            </div>174            <div class="view" role="tabpanel" id="view-diff" aria-labelledby="tab-diff" tabindex="0" hidden>175              <div class="diff-legend"><span><del>removed</del> from the input</span><span><ins>inserted</ins> by HTR</span><span class="muted" id="diff-sim"></span></div>176              <div class="result-text diff" id="diff"></div>177            </div>178            <div class="view" role="tabpanel" id="view-checks" aria-labelledby="tab-checks" tabindex="0" hidden>179              <ul class="checks" id="checks"></ul>180              <p class="muted small">Checks compare the reconstruction with your input. They cannot tell whether the reconstruction matches an unknown original.</p>181            </div>182          </div>183          <div class="pane-foot result-foot">184            <span class="status" id="status" aria-live="polite"></span>185            <div class="result-actions">186              <button class="icon-btn sm" id="copy" type="button" disabled aria-label="Copy reconstruction" title="Copy"><svg aria-hidden="true"><use href="#i-copy"/></svg></button>187              <button class="icon-btn sm" id="dl-txt" type="button" disabled aria-label="Download as .txt" title="Download .txt"><svg aria-hidden="true"><use href="#i-down"/></svg><span class="ext">txt</span></button>188              <button class="icon-btn sm" id="dl-json" type="button" disabled aria-label="Download as .json" title="Download .json"><svg aria-hidden="true"><use href="#i-down"/></svg><span class="ext">json</span></button>189              <button class="icon-btn sm" id="share" type="button" aria-label="Copy a share link for this input" title="Share link (text kept in the URL, not on the server)"><svg aria-hidden="true"><use href="#i-link"/></svg></button>190            </div>191          </div>192        </div>193      </div>194195196      <div class="actionbar" id="actionbar">197        <div class="ab-left">198          <fieldset class="seg seg-compact" id="seg-beam" aria-label="Decoding">199            <legend class="sr">Decoding</legend>200            <label><input type="radio" name="beam" value="1" checked><span>Greedy <small>fast</small></span></label>201            <label><input type="radio" name="beam" value="3"><span>Beam 3 <small>slower</small></span></label>202          </fieldset>203          <span class="ab-note muted" id="beam-note" hidden>greedy only for backbones</span>204          <span class="ab-ctx muted" id="ab-ctx"></span>205        </div>206        <button class="btn btn-primary btn-go" id="go" type="button"><span class="go-spin" aria-hidden="true"></span><span class="go-label">Reconstruct</span> <kbd class="go-kbd" aria-hidden="true"><span id="kbd-mod2">⌘</span>↵</kbd></button>207      </div>208    </div>209  </section>210211  <section class="section" id="how" aria-labelledby="how-title">212    <div class="wrap">213      <div class="sec-head">214        <p class="kicker">02 · How it works</p>215        <h2 id="how-title">Four deterministic steps around the model you choose</h2>216      </div>217      <ol class="steps">218        <li class="step">219          <svg viewBox="0 0 160 80" aria-hidden="true"><rect x="6" y="14" width="148" height="52" rx="10" class="s-box"/><path d="M18 32h28M18 48h18" class="s-line"/><rect x="54" y="25" width="34" height="14" rx="4" class="s-acc"/><text x="71" y="35.5" class="s-t">[12]</text><path d="M96 32h44M44 48h20" class="s-line"/><rect x="70" y="41" width="40" height="14" rx="4" class="s-acc"/><text x="90" y="51.5" class="s-t">$x^2$</text><path d="M118 48h22" class="s-line"/></svg>220          <h3><span class="n">1</span>Protect</h3>221          <p>Citations, equations and URLs are swapped for opaque placeholders so the model cannot rewrite them.</p>222        </li>223        <li class="step">224          <svg viewBox="0 0 160 80" aria-hidden="true"><g class="s-tok"><rect x="8" y="30" width="22" height="20" rx="5"/><rect x="34" y="30" width="30" height="20" rx="5"/><rect x="68" y="30" width="18" height="20" rx="5"/><rect x="90" y="30" width="34" height="20" rx="5"/><rect x="128" y="30" width="24" height="20" rx="5"/></g><path d="M19 58v8M49 58v8M77 58v8M107 58v8M140 58v8" class="s-line thin"/><path d="M12 70h136" class="s-line"/><path d="M19 22v-8M49 22v-8M77 22v-8M107 22v-8M140 22v-8" class="s-line thin"/></svg>225          <h3><span class="n">2</span>Encode</h3>226          <p>HTR models tokenise the protected text with their 32 k SentencePiece vocabulary (≤ 640 tokens); the pretrained backbones use their own tokenizer and receive the context as a text prefix.</p>227        </li>228        <li class="step">229          <svg viewBox="0 0 160 80" aria-hidden="true"><rect x="8" y="18" width="52" height="44" rx="10" class="s-box"/><text x="34" y="44" class="s-t big">enc</text><path d="M64 40h22" class="s-arrow"/><rect x="92" y="18" width="60" height="44" rx="10" class="s-box"/><text x="122" y="44" class="s-t big">dec</text><path d="M110 70c8 6 16 6 24 0" class="s-arrow"/></svg>230          <h3><span class="n">3</span>Decode</h3>231          <p>The decoder generates the reconstruction token by token — greedy or beam 3 for the HTR models, greedy for the backbones — seeded and deterministic.</p>232        </li>233        <li class="step">234          <svg viewBox="0 0 160 80" aria-hidden="true"><rect x="6" y="14" width="96" height="52" rx="10" class="s-box"/><path d="M18 32h70M18 48h44" class="s-line"/><circle cx="128" cy="26" r="11" class="s-ok"/><path d="M122.5 26.5l3.6 3.6 7-7" class="s-chk"/><circle cx="128" cy="54" r="11" class="s-warn"/><path d="M128 49v6M128 59v.3" class="s-chk"/></svg>235          <h3><span class="n">4</span>Restore &amp; check</h3>236          <p>Placeholders are restored, then numbers, citations, negations, hedges and length are compared with the input.</p>237        </li>238      </ol>239    </div>240  </section>241242  <section class="section limits-sec" id="limits" aria-labelledby="limits-title">243    <div class="wrap">244      <div class="limits">245        <div class="limits-head">246          <p class="kicker">03 · What it is not</p>247          <h2 id="limits-title">Read this before using any output</h2>248          <p class="sec-lede">Reconstruction from a paraphrase is non-identifiable: many originals share one rewrite. The output is one plausible estimate.</p>249        </div>250        <ul class="nots">251          <li><svg aria-hidden="true"><use href="#i-not"/></svg><div><strong>Not the original text.</strong> It is a synthetic reconstruction, generated by a model.</div></li>252          <li><svg aria-hidden="true"><use href="#i-not"/></svg><div><strong>Not evidence of human authorship</strong> — nor of AI use. Do not use HTR for AI-text detection or authorship attribution.</div></li>253          <li><svg aria-hidden="true"><use href="#i-not"/></svg><div><strong>Not for academic-integrity decisions</strong>, grading, hiring, or any judgement about a person.</div></li>254          <li><svg aria-hidden="true"><use href="#i-not"/></svg><div><strong>Not a fact checker.</strong> Numbers, citations and negations can still change: verify every one against your source.</div></li>255          <li><svg aria-hidden="true"><use href="#i-not"/></svg><div><strong>Not a finished model.</strong> <span id="limits-pilot">This server runs four Medium-stage research models: two HTR Transformers trained from scratch (Tiny, the paper's confirmatory model; Base) and two pretrained backbones fine-tuned on the same 72 698 validated rewrite→original pairs (Flan-T5-Large, Qwen2.5-1.5B). All of them are trained on rights-verified pre-2018 passages (PMC Open Access, CC BY economics and finance journals, arXiv, public-domain books). Gains in chrF++ over the untouched input are small by construction — from +0.4 (Tiny, confirmatory) to about +2 (Qwen, exploratory) — because reconstruction from a paraphrase is non-identifiable.</span></div></li>256          <li><svg aria-hidden="true"><use href="#i-not"/></svg><div><strong>Not memorisation-proof for the backbones.</strong> <span id="limits-backbone">Flan-T5 and Qwen are pretrained backbones: their pretraining corpus may contain pre-2018 scientific text, and the memorisation controls of the paper cover only the HTR training pairs (see its threats-to-validity section). Their outputs remain synthetic reconstructions.</span></div></li>257        </ul>258      </div>259    </div>260  </section>261262  <section class="section" id="model" aria-labelledby="model-title">263    <div class="wrap">264      <div class="sec-head">265        <p class="kicker">04 · Models</p>266        <h2 id="model-title"><span id="m-name">{{N_MODELS}} reconstruction models</span></h2>267        <p class="sec-lede" id="m-data">Two HTR Transformers trained from scratch and two pretrained backbones fine-tuned on the same pairs. Pick one in the workbench; the default is <code>{{MODEL}}</code>.</p>268      </div>269      <dl class="tiles" id="m-tiles"></dl>270      <div class="metrics-card">271        <div class="metrics-head">272          <h3>Comparison · Δ chrF++ versus the identity baseline</h3>273          <p class="muted small">Differences in chrF++ against returning the input unchanged (B0), Medium Haiku pairs. Exploratory, except the confirmatory test value of HTR-Tiny (95 % interval in brackets; ± as reported). Number recall and placeholder exactness are preservation rates on the test split.</p>274        </div>275        <div class="table-wrap"><table class="metrics compare" id="metrics"><thead><tr><th scope="col">Model</th><th scope="col" class="num">Params</th><th scope="col" class="num">Val Δ</th><th scope="col" class="num">Test Δ</th><th scope="col" class="num">Held-out domain Δ</th><th scope="col" class="num">Held-out period Δ</th><th scope="col" class="num">Numbers</th><th scope="col" class="num">Placeholders</th><th scope="col" class="num">Pangram Human</th><th scope="col" class="num">Mean AI score</th><th scope="col" class="num">Flagged</th></tr></thead><tbody></tbody></table></div>276        <p class="pg-note table-note"><svg aria-hidden="true"><use href="#i-info"/></svg><span><b>Pangram 4.1 (n = 54 test passages).</b> Human originals: 0 % flagged, mean 0.000; LLM rewrites (the model input): 46 % flagged, mean 0.188. This measures one commercial detector's behaviour on a 54-passage sample. A low AI-likelihood is not evidence of human authorship, and HTR must not be used to evade AI-text detection or for integrity decisions.</span></p>277        <p class="metrics-foot" id="metrics-foot"><a class="text-link" href="/model-card">Default model card <svg aria-hidden="true"><use href="#i-arrow"/></svg></a> <a class="text-link" href="/api/models">/api/models</a> <a class="text-link" href="/api/stats">/api/stats</a></p>278      </div>279    </div>280  </section>281282  <section class="section" id="api" aria-labelledby="api-title">283    <div class="wrap api-grid">284      <div>285        <div class="sec-head">286          <p class="kicker">05 · API</p>287          <h2 id="api-title">One endpoint. JSON in, JSON out.</h2>288          <p class="sec-lede">No key, no account, no tracking. Be gentle: one Mac mini serves everyone.</p>289        </div>290        <ul class="limits-list">291          <li><strong>8 000</strong> characters per request (HTR models read ≈ 640 tokens, Flan-T5 512; longer inputs are truncated with a warning)</li>292          <li><strong>30</strong> requests per minute per client, <strong>10</strong> for the pretrained backbones (<code>429</code> + <code>Retry-After</code>)</li>293          <li><strong>1</strong> inference at a time per model; <code>beam</code> applies to HTR models only. Latency <span id="api-lat">≈0.3 s (Tiny) to ≈2 s (Qwen) per paragraph</span></li>294        </ul>295        <div class="table-wrap"><table class="endpoints">296          <tbody>297            <tr><td><span class="verb post">POST</span></td><td><code>/api/reconstruct</code></td><td>reconstruct one passage</td></tr>298            <tr><td><span class="verb">GET</span></td><td><code>/api/models</code></td><td>model cards, <code>loaded</code> flag, default</td></tr>299            <tr><td><span class="verb">GET</span></td><td><code>/api/info</code></td><td>default model metadata &amp; model ids</td></tr>300            <tr><td><span class="verb">GET</span></td><td><code>/api/stats</code></td><td>per-model requests, latency p50/p95, limits</td></tr>301            <tr><td><span class="verb">GET</span></td><td><code>/api/examples</code></td><td>example inputs</td></tr>302            <tr><td><span class="verb">GET</span></td><td><code>/health</code></td><td>liveness</td></tr>303            <tr><td><span class="verb">GET</span></td><td><code>/model-card/&lt;id&gt;</code></td><td>model card (<code>?raw</code> for Markdown; no id = default)</td></tr>304          </tbody>305        </table></div>306      </div>307      <div class="code-card">308        <div class="tabs code-tabs" role="tablist" aria-label="Code examples">309          <button role="tab" aria-selected="true" aria-controls="code-curl" id="ct-curl" type="button">curl</button>310          <button role="tab" aria-selected="false" aria-controls="code-py" id="ct-py" tabindex="-1" type="button">Python</button>311          <button role="tab" aria-selected="false" aria-controls="code-js" id="ct-js" tabindex="-1" type="button">JavaScript</button>312          <button role="tab" aria-selected="false" aria-controls="code-resp" id="ct-resp" tabindex="-1" type="button">Response</button>313          <button class="icon-btn sm code-copy" id="code-copy" type="button" aria-label="Copy code"><svg aria-hidden="true"><use href="#i-copy"/></svg></button>314        </div>315<pre role="tabpanel" id="code-curl" aria-labelledby="ct-curl"><code>curl -s {{URL}}/api/reconstruct \316  -H 'Content-Type: application/json' \317  -d '{318    "text": "…LLM-rewritten passage…",319    "model": "qwen2.5-1.5b-htr",320    "discipline": "economics",321    "pub_year": 2012,322    "section_role": "results",323    "beam": 1324  }'325# model ids: curl -s {{URL}}/api/models | jq '.models[].id'</code></pre>326<pre role="tabpanel" id="code-py" aria-labelledby="ct-py" hidden><code>import json, urllib.request327328req = urllib.request.Request(329    "{{URL}}/api/reconstruct",330    data=json.dumps({"text": "…LLM-rewritten passage…",331                     "model": "htr-tiny-0.3.0",   # or omit: default model332                     "discipline": "economics", "beam": 1}).encode(),333    headers={"Content-Type": "application/json"},334)335r = json.load(urllib.request.urlopen(req))336print(r["model"], r["latency_s"], "s")337print(r["reconstruction"])338for w in r["warnings"]:339    print("check:", w)</code></pre>340<pre role="tabpanel" id="code-js" aria-labelledby="ct-js" hidden><code>const r = await fetch("{{URL}}/api/reconstruct", {341  method: "POST",342  headers: { "Content-Type": "application/json" },343  body: JSON.stringify({ text: "…LLM-rewritten passage…", model: "flan-t5-large-htr" }),344}).then((res) =&gt; res.json());345346console.log(r.model, r.reconstruction, r.warnings);</code></pre>347<pre role="tabpanel" id="code-resp" aria-labelledby="ct-resp" hidden><code>{348  "reconstruction": "…",            // synthetic text349  "warnings": ["…"],                // preservation issues350  "preservation": {351    "number_recall": 1.0,           // input numbers kept352    "number_precision": 1.0,        // no invented numbers353    "placeholders_exact": 1.0,      // citations/math/URLs intact354    "negation_delta": 0, "hedge_delta": 0,355    "sentence_count_delta": 0356  },357  "diff_html": "… &lt;del&gt;…&lt;/del&gt; &lt;ins&gt;…&lt;/ins&gt; …",358  "diff_stats": { "words_added": 3, "words_removed": 4, … },359  "metadata_used": { "discipline": "economics", "arch": "hf-causal" },360  "model": "Qwen2.5-1.5B-HTR", "model_id": "qwen2.5-1.5b-htr",361  "family": "hf-causal", "device": "mps",362  "beam": 1, "beam_requested": 3, "decoding": "greedy",363  "decoding_note": "beam search is only offered for HTR models; …",364  "latency_s": 8.4, "input_text": "…", "notice": "…"365}</code></pre>366      </div>367    </div>368  </section>369370  <section class="section research-sec" id="research" aria-labelledby="research-title">371    <div class="wrap research">372      <div>373        <p class="kicker">06 · Research</p>374        <h2 id="research-title">Human Text Reconstruction: Learning the Inverse of LLM-Induced Transformations in Scientific Writing</h2>375        <p class="sec-lede">Simon-Pierre Boucher · Université du Québec en Outaouais · Working Paper AI-0002 (2026)</p>376        <p>Training pairs are built from rights-verified scientific passages published before 2018 (PMC Open Access, CC-BY economics and finance journals, arXiv, public-domain reference books) and their rewrites by a large language model; the model learns the inverse map. This server compares the paper's HTR Transformers (Tiny, Base) with two pretrained backbones fine-tuned on the same pairs (Flan-T5-Large, Qwen2.5-1.5B); larger variants (Flan-T5-XL, Qwen2.5-3B, HTR-Large) can be added without a code change.</p>377        <p class="small muted">Weights and code: Apache-2.0 (non-commercial research use where CC-BY-NC sources were included); the backbones keep the Apache-2.0 licence of google/flan-t5-large and Qwen/Qwen2.5-1.5B.</p>378      </div>379      <div class="cite">380        <div class="cite-head"><span>Cite</span><button class="icon-btn sm" id="cite-copy" type="button" aria-label="Copy citation"><svg aria-hidden="true"><use href="#i-copy"/></svg></button></div>381<pre id="cite"><code>@techreport{boucher2026htr,382  author      = {Boucher, Simon-Pierre},383  title       = {Human Text Reconstruction: Learning the384                 Inverse of LLM-Induced Transformations385                 in Scientific Writing},386  institution = {Universit\'e du Qu\'ebec en Outaouais},387  type        = {Working Paper},388  number      = {AI-0002},389  year        = {2026},390  url         = {https://htr.spboucher.ai}391}</code></pre>392      </div>393    </div>394  </section>395</main>396397<footer class="foot">398  <div class="wrap foot-in">399    <div class="foot-brand"><svg class="brand-mark" aria-hidden="true"><use href="#logo"/></svg><div><strong>HTR</strong> · Human Text Reconstruction<br><span class="muted small">Research preview of UQO Working Paper AI-0002. Synthetic reconstructions — never evidence of authorship or of AI use.</span></div></div>400    <nav class="foot-nav" aria-label="Footer">401      <a href="#workbench">Workbench</a><a href="/model-card">Model cards</a><a href="/api/models">Models API</a><a href="/api/stats">Service stats</a><a href="/health">Health</a><a href="https://www.spboucher.ai">spboucher.ai</a>402    </nav>403    <p class="foot-meta muted small">No cookies, no analytics, no third-party requests. Platform v{{VERSION}} · © 2026 Simon-Pierre Boucher, UQO.</p>404  </div>405</footer>406407<div class="scrim" id="scrim" hidden></div>408<aside class="drawer" id="history" role="dialog" aria-modal="true" aria-labelledby="history-title" hidden>409  <div class="drawer-head"><h2 id="history-title">Recent runs</h2><button class="icon-btn" id="history-close" type="button" aria-label="Close history"><svg aria-hidden="true"><use href="#i-x"/></svg></button></div>410  <p class="muted small drawer-note">Stored only in this browser (last 10).</p>411  <ol class="history-list" id="history-list"></ol>412  <div class="drawer-foot"><button class="link-btn" id="history-clear" type="button">Clear history</button></div>413</aside>414<div class="toast" id="toast" role="status" aria-live="polite"></div>415416<script type="application/json" id="boot">{{BOOT}}</script>417</body>418</html>419
Files main
Menu

Theme