Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <link rel="icon" type="image/svg+xml" href="/ccr-logo.svg"> | |
| <title>CCR Platform - Testing Guide</title> | |
| <style> | |
| :root { | |
| --bg: #ffffff; --fg: #1a1a1a; --muted: #666; --border: #ddd; | |
| --accent: #26736f; --card: #f7f7f8; --amber-bg: #fff7e0; --amber-border: #e0b84d; | |
| --code-bg: #f0f0f2; --brand: #151515; | |
| } | |
| @media (prefers-color-scheme: dark) { | |
| :root { | |
| --bg: #16181c; --fg: #e6e6e6; --muted: #9a9a9a; --border: #3a3d44; | |
| --accent: #6cc9c6; --card: #1f2228; --amber-bg: #2e2810; --amber-border: #8a6d1f; | |
| --code-bg: #24272e; | |
| } | |
| } | |
| * { box-sizing: border-box; } | |
| body { | |
| margin: 0; background: var(--bg); color: var(--fg); | |
| font: 16px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; | |
| } | |
| /* Topbar mirrors the app header EXACTLY (gradient, height, logo size, | |
| tagline, link styles) so navigating app <-> docs doesn't jump. Update | |
| styles.css .header alongside any change here. */ | |
| .topbar { | |
| background: linear-gradient(180deg, #1b1b1c, var(--brand)); color: #fff; | |
| padding: 14px 28px; | |
| display: flex; align-items: center; gap: 14px; flex-wrap: wrap; | |
| position: sticky; top: 0; z-index: 30; | |
| border-bottom: 1px solid rgba(255,255,255,.07); | |
| } | |
| .topbar .brand { display: inline-flex; align-items: center; text-decoration: none; } | |
| .brand-logo { height: 28px; width: auto; display: block; } | |
| .topbar .brand:hover { opacity: .88; } | |
| .topbar .lab { | |
| flex: 1 1 280px; min-width: 0; font-size: 12.5px; line-height: 1.5; | |
| color: #fff; opacity: .85; | |
| } | |
| .topbar nav { margin-left: auto; display: flex; align-items: center; gap: 14px; flex-wrap: wrap; } | |
| .topbar nav a { color: rgba(255,255,255,.82); text-decoration: none; font-size: 13px; } | |
| .topbar nav a:hover { color: #fff; text-decoration: underline; } | |
| .topbar nav a.current { color: #fff; font-weight: 600; } | |
| .topbar .topbar-btn { | |
| background: rgba(255,255,255,.12); color: #fff; | |
| border: 1px solid rgba(255,255,255,.45); | |
| padding: 5px 14px; border-radius: 9px; font-size: 13px; text-decoration: none; | |
| } | |
| .topbar .topbar-btn:hover { background: rgba(255,255,255,.22); text-decoration: none; } | |
| main { max-width: 860px; margin: 0 auto; padding: 2rem 1.25rem 4rem; } | |
| h1 { font-size: 1.7rem; margin: 0 0 .25rem; } | |
| h2 { font-size: 1.25rem; margin: 2.2rem 0 .6rem; padding-top: .6rem; border-top: 1px solid var(--border); } | |
| h3 { font-size: 1.02rem; margin: 1.2rem 0 .4rem; } | |
| p, li { color: var(--fg); } | |
| .sub { color: var(--muted); margin: 0 0 1.2rem; } | |
| a { color: var(--accent); } | |
| code { background: var(--code-bg); padding: .1em .35em; border-radius: 4px; font-size: .9em; } | |
| .note { | |
| background: var(--amber-bg); border: 1px solid var(--amber-border); | |
| border-radius: 8px; padding: .8rem 1rem; margin: 1rem 0; | |
| } | |
| .note b { display: block; margin-bottom: .25rem; } | |
| .tablewrap { overflow-x: auto; } | |
| table { border-collapse: collapse; width: 100%; margin: .8rem 0; font-size: .93rem; } | |
| th, td { border: 1px solid var(--border); padding: .45rem .6rem; text-align: left; vertical-align: top; } | |
| th { background: var(--card); } | |
| ol li, ul li { margin: .3rem 0; } | |
| .dl::before { content: "⬇ "; font-size: .85em; } | |
| .top { position: fixed; right: 1rem; bottom: 1rem; background: var(--card); | |
| border: 1px solid var(--border); border-radius: 8px; padding: .4rem .7rem; | |
| text-decoration: none; font-size: .85rem; } | |
| figure { margin: 1rem 0 1.4rem; } | |
| figure svg { width: 100%; height: auto; border: 1px solid var(--border); | |
| border-radius: 8px; background: var(--card); } | |
| figcaption { color: var(--muted); font-size: .85rem; margin-top: .4rem; } | |
| .box { fill: var(--bg); stroke: var(--border); stroke-width: 1.5; } | |
| .box-accent { fill: none; stroke: var(--accent); stroke-width: 2; } | |
| .lbl { fill: var(--fg); font: 600 13px sans-serif; } | |
| .lbl-sm { fill: var(--muted); font: 11px sans-serif; } | |
| .flow { stroke: var(--muted); stroke-width: 1.5; fill: none; marker-end: url(#arw); } | |
| /* Shareable section links: a "#" appears on hover; click a heading to copy | |
| a direct link to that section. */ | |
| h2[id], h3[id] { scroll-margin-top: 1rem; } | |
| .anchor { | |
| opacity: 0; text-decoration: none; color: var(--muted); font-weight: 400; | |
| margin-left: .4rem; cursor: pointer; transition: opacity .12s; | |
| } | |
| h2:hover .anchor, h3:hover .anchor, .anchor:focus { opacity: .7; } | |
| .anchor:hover { opacity: 1; color: var(--accent); } | |
| :target { animation: flash 1.4s ease-out; } | |
| @keyframes flash { | |
| from { background: var(--amber-bg); } | |
| to { background: transparent; } | |
| } | |
| .toast { | |
| position: fixed; left: 50%; bottom: 1.5rem; transform: translateX(-50%); | |
| background: var(--brand); color: #fff; padding: .5rem .9rem; border-radius: 8px; | |
| font-size: .85rem; opacity: 0; pointer-events: none; transition: opacity .2s; | |
| } | |
| .toast.show { opacity: 1; } | |
| @media (prefers-reduced-motion: reduce) { | |
| :target { animation: none; } | |
| .anchor { transition: none; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header class="topbar"> | |
| <a class="brand" href="/"><svg class="brand-logo" viewBox="188 455 880 338" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"> | |
| <g fill="none" stroke="#fff" stroke-width="32"> | |
| <path d="M 458.884 538.509 A 133 133 0 1 0 458.884 709.491"/> | |
| <path d="M 563.116 538.509 A 133 133 0 0 1 766.884 538.509"/> | |
| <path d="M 563.116 709.491 A 133 133 0 0 0 766.884 709.491"/> | |
| <path d="M 846 754 V 496 H 950 A 73 62 0 0 1 950 620 H 846"/> | |
| <path d="M 930 620 L 1035 759"/> | |
| </g> | |
| <circle cx="481" cy="624" r="15" fill="#339B98"/> | |
| <circle cx="538" cy="624" r="15" fill="#339B98"/> | |
| </svg></a> | |
| <span class="lab">Psychological Text Analysis with Contextualized Construct Representation</span> | |
| <nav> | |
| <a href="/welcome">About</a> | |
| <a href="/guide">Guide</a> | |
| <a href="/testing" class="current">Testing</a> | |
| <a href="/product" id="nav-product" hidden>How it works</a> | |
| <a class="topbar-btn" href="/">Open dashboard</a> | |
| </nav> | |
| </header> | |
| <main> | |
| <h1>Testing guide</h1> | |
| <p class="sub">Everything built so far, as click-through scenarios: what to do and exactly what | |
| you should see. Every dataset referenced is downloadable right here - all texts are | |
| synthetic, written for this kit; no real participant data anywhere. This is the lab's | |
| internal testing guide; the plain how-to-use walkthrough for everyone lives at | |
| <a href="/guide">the public guide</a>.</p> | |
| <div class="note"> | |
| <b>⚠ This is the dev instance - a couple of things to know:</b> | |
| <ul> | |
| <li><b>Your work is saved.</b> Account, projects, uploaded datasets, and runs | |
| are backed by persistent storage and stay put across restarts.</li> | |
| <li><b>It sleeps when idle.</b> After ~48 h without visitors, the first page | |
| load takes about a minute to wake it up.</li> | |
| <li>Please still avoid uploading sensitive or identifiable data on this dev | |
| instance.</li> | |
| </ul> | |
| </div> | |
| <h2 id="quickstart">Quickstart: run YOUR study in 5 minutes</h2> | |
| <ol> | |
| <li><b>Sign in</b> (top right - Google or email+password). Lab accounts have | |
| unlimited access.</li> | |
| <li><b>Create a project</b> named after your study.</li> | |
| <li><b>Upload your corpus</b> - any CSV/XLSX with one text per row. Other columns | |
| (IDs, conditions, demographics) are fine; they pass through untouched into the | |
| results file.</li> | |
| <li><b>Pick your construct(s)</b> - search the library (94 scales from the lab's | |
| collection), or click "+ New construct" and choose a card: type/paste items, upload a file, or draft items with AI for a construct with no validated questionnaire. | |
| Pick several (up to 10) to score them together in a single run and see how | |
| they correlate in your texts.</li> | |
| <li><b>Run.</b> Read the warnings panel first (it tells you if something about your | |
| data is off), then check the top/bottom scoring texts - if those don't make sense | |
| for your construct, trust that instinct and report it.</li> | |
| <li><b>Export</b> the results CSV (your columns + per-item similarities + CCR score) | |
| and, if you want, the Python script that reproduces the run on your own machine.</li> | |
| </ol> | |
| <p>The sections below are structured test scenarios with sample data - useful for | |
| systematically stress-testing the platform, but <b>your real data is the best test we | |
| have</b>.</p> | |
| <h2 id="limits">Limits at a glance</h2> | |
| <p>Accounts come in four tiers, set by the admins: <b>external user</b> (the default on | |
| sign-up), <b>lab member</b>, <b>maintainer</b>, and <b>PI</b>. Signing in lifts the | |
| anonymous caps; lab members and above have no saved-run cap. The row limit is usually | |
| what you hit first, not the file size.</p> | |
| <div class="tablewrap"> | |
| <table> | |
| <tr><th>Limit</th><th>Signed out</th><th>External user</th><th>Lab member +</th></tr> | |
| <tr><td>Upload size</td><td>5 MB</td><td>50 MB</td><td>50 MB</td></tr> | |
| <tr><td>Rows per file</td><td>200</td><td>50,000</td><td>50,000</td></tr> | |
| <tr><td>Runs per day</td><td>3, then sign in</td><td>unlimited</td><td>unlimited</td></tr> | |
| <tr><td>Saved runs kept</td><td>none (file deleted after each run)</td><td>15</td><td>unlimited</td></tr> | |
| <tr><td>AI item drafts per day</td><td>0 (sign in to use)</td><td>20</td><td>20</td></tr> | |
| </table> | |
| </div> | |
| <p>Every model below is available on all three, including signed out.</p> | |
| <h2 id="models">Models available</h2> | |
| <p>Chosen on the Step 3 card. Scores are only comparable <i>within</i> the same model - | |
| never across model families. Larger models are slower and, the first time anyone selects | |
| one on this instance, take a couple of extra minutes to download before the run starts; | |
| after that they stay warm.</p> | |
| <div class="tablewrap"> | |
| <table> | |
| <tr><th>Model</th><th>Best for</th><th>Notes</th></tr> | |
| <tr><td>MiniLM L6 v2 <b>(default)</b></td><td>English, general use</td><td>Fast; the CCR reference model. Start here.</td></tr> | |
| <tr><td>E5 Large v2</td><td>English, higher quality</td><td>Stronger but noticeably slower.</td></tr> | |
| <tr><td>Multilingual E5 Base</td><td>50+ languages</td><td>Use for non-English corpora.</td></tr> | |
| <tr><td>PsyEmbedding BERT / RoBERTa / GTE / E5 Large</td><td>Psychological text</td><td>Four lab fine-tunes for psychology research. English; heavier, so the first run downloads ~1.3 GB.</td></tr> | |
| </table> | |
| </div> | |
| <h2 id="samples">0. Sample datasets</h2> | |
| <p>One file per platform behavior. To test something, download the file named for it and | |
| follow its scenario below. Unless stated otherwise, select language <b>English</b> and | |
| model <b>MiniLM</b>.</p> | |
| <div class="tablewrap"> | |
| <table> | |
| <tr><th>File</th><th>Demonstrates</th></tr> | |
| <tr><td><a class="dl" href="/samples/sample_corpus.csv" download>sample_corpus.csv</a></td><td>Clean baseline run (60 rows, no warnings)</td></tr> | |
| <tr><td><a class="dl" href="/samples/warnings_showcase.csv" download>warnings_showcase.csv</a></td><td>All text-QA warnings at once</td></tr> | |
| <tr><td><a class="dl" href="/samples/french_demo.csv" download>french_demo.csv</a></td><td>Language mismatch / model-language checks</td></tr> | |
| <tr><td><a class="dl" href="/samples/demo_spanish.csv" download>demo_spanish.csv</a></td><td>Same checks in Spanish + short-text rows</td></tr> | |
| <tr><td><a class="dl" href="/samples/mixed_language_demo.csv" download>mixed_language_demo.csv</a></td><td>Uncertain language detection (15 EN + 15 ES)</td></tr> | |
| <tr><td><a class="dl" href="/samples/long_documents_demo.csv" download>long_documents_demo.csv</a></td><td>Token-window truncation warning</td></tr> | |
| <tr><td><a class="dl" href="/samples/moral_foundations_demo.csv" download>moral_foundations_demo.csv</a></td><td>Meaningful score spread across MFQ-2 foundations</td></tr> | |
| <tr><td><a class="dl" href="/samples/multi_column_demo.csv" download>multi_column_demo.csv</a></td><td>Text-column auto-suggestion (5 columns)</td></tr> | |
| <tr><td><a class="dl" href="/samples/semicolon_delimited_demo.csv" download>semicolon_delimited_demo.csv</a></td><td>Delimiter sniffing (semicolons, commas inside texts)</td></tr> | |
| <tr><td><a class="dl" href="/samples/latin1_encoding_demo.csv" download>latin1_encoding_demo.csv</a></td><td>Non-UTF-8 encoding fallback</td></tr> | |
| <tr><td><a class="dl" href="/samples/xlsx_upload_demo.xlsx" download>xlsx_upload_demo.xlsx</a></td><td>Excel ingestion path</td></tr> | |
| <tr><td><a class="dl" href="/samples/large_demo.csv" download>large_demo.csv</a></td><td>Anonymous upload caps (800 rows)</td></tr> | |
| <tr><td><a class="dl" href="/samples/construct_items_demo.csv" download>construct_items_demo.csv</a></td><td>Construct upload: item + reverse columns</td></tr> | |
| <tr><td><a class="dl" href="/samples/construct_items_marker_demo.csv" download>construct_items_marker_demo.csv</a></td><td>Construct upload: (R) markers, blank + duplicate rows</td></tr> | |
| <tr><td><a class="dl" href="/samples/construct_items_demo.xlsx" download>construct_items_demo.xlsx</a></td><td>Construct upload from Excel</td></tr> | |
| </table> | |
| </div> | |
| <h2 id="projects">1. Projects and sidebar</h2> | |
| <ol> | |
| <li>Create three projects. They appear under "Today", newest activity first.</li> | |
| <li>Type in the sidebar search box: the list filters as you type.</li> | |
| <li>Archive a project (project header > Archive): it moves into the collapsed | |
| "Archived" group; Unarchive brings it back. No data is lost either way.</li> | |
| <li>Delete a project: requires typing the project name; removes its datasets, | |
| runs, and files permanently.</li> | |
| </ol> | |
| <h2 id="uploads">2. Upload paths (Step 1 card)</h2> | |
| <div class="tablewrap"> | |
| <table> | |
| <tr><th>Upload</th><th>Expect</th></tr> | |
| <tr><td><a href="/samples/sample_corpus.csv" download>sample_corpus.csv</a></td><td>Parses, 60 rows, <code>text</code> column suggested</td></tr> | |
| <tr><td><a href="/samples/multi_column_demo.csv" download>multi_column_demo.csv</a></td><td>5 columns; <code>comment_text</code> marked "(suggested)"</td></tr> | |
| <tr><td><a href="/samples/semicolon_delimited_demo.csv" download>semicolon_delimited_demo.csv</a></td><td>Parses into exactly id + text (commas inside texts intact)</td></tr> | |
| <tr><td><a href="/samples/latin1_encoding_demo.csv" download>latin1_encoding_demo.csv</a></td><td>Parses with a ⚠ note: decoded as latin-1; fiancée/café render correctly</td></tr> | |
| <tr><td><a href="/samples/xlsx_upload_demo.xlsx" download>xlsx_upload_demo.xlsx</a></td><td>Parses like a CSV</td></tr> | |
| <tr><td>any <code>.txt</code> or <code>.pdf</code> file</td><td>Rejected: unsupported file type</td></tr> | |
| </table> | |
| </div> | |
| <p>Anonymous limits (signed out): the Step 1 hint shows 5 MB / 200 rows and says uploads | |
| are deleted after analysis. Upload | |
| <a href="/samples/large_demo.csv" download>large_demo.csv</a> (800 rows): rejected with a | |
| "Sign in (top right)" message. Sign in and retry: accepted.</p> | |
| <h2 id="constructs">3. Construct selection (Step 2 card)</h2> | |
| <ol> | |
| <li>Open the picker: search field + panel below it, library grouped by category, | |
| with "Recently used" pinned on top after your first runs.</li> | |
| <li>Type "GAD" or "empathy": matches by name and category; Arrow keys + Enter work.</li> | |
| <li>Select any imported construct: items listed, plus the "not yet verified verbatim" | |
| notice (expected for the whole imported library for now).</li> | |
| </ol> | |
| <h3>Multi-construct runs (new)</h3> | |
| <ol> | |
| <li>Pick a construct, then open the picker again and pick a second - selected ones | |
| show a ✓ (clicking again removes). Each selection becomes a collapsible block | |
| with its items and a "remove" link. Up to 10 constructs per run.</li> | |
| <li>The run button reads "Run CCR analysis (2 constructs)". All constructs are | |
| scored on <b>one pass</b> over the corpus, so two constructs take about as long | |
| as one.</li> | |
| <li>Results open with a <b>"Construct interrelations"</b> card - the Pearson | |
| correlation between per-text scores, i.e. how the constructs co-occur in YOUR | |
| texts - plus a collapsible per-construct section (histogram, item loadings, | |
| top/bottom texts). Try | |
| <a href="/samples/moral_foundations_demo.csv" download>moral_foundations_demo.csv</a> | |
| with two MFQ-2 foundations.</li> | |
| <li>The export CSV keeps one row per text with per-construct prefixed columns | |
| (<code>mfq_care_sim_item_1</code> … <code>mfq_care_ccr_score</code>, …), so the | |
| correlations are fully recomputable; metadata and the reproduction script cover | |
| every construct in the run. Single-construct runs are unchanged.</li> | |
| </ol> | |
| <h3>Custom construct, typed</h3> | |
| <ol> | |
| <li>"+ New construct" > the "Type or paste" card > name it, paste items one per line.</li> | |
| <li>Append <code>(R)</code> to one line: the form shows "1 item(s) marked reverse-scored".</li> | |
| <li>Save: it appears in the picker under "My custom constructs"; run metadata carries | |
| the reverse flag (check via Results > metadata download).</li> | |
| </ol> | |
| <h3>Custom construct, from file</h3> | |
| <ol> | |
| <li>"+ New construct" > the "Upload a file" card.</li> | |
| <li>Try <a href="/samples/construct_items_demo.csv" download>construct_items_demo.csv</a> | |
| (<code>item,reverse</code> columns - 1/true/yes/R = reverse), | |
| <a href="/samples/construct_items_marker_demo.csv" download>construct_items_marker_demo.csv</a> | |
| (single column with <code>(R)</code> markers), or | |
| <a href="/samples/construct_items_demo.xlsx" download>construct_items_demo.xlsx</a> (Excel).</li> | |
| <li>Expect: items fill the textarea ((R) appended where flagged), the filename becomes | |
| the suggested name, and parse notes list skipped duplicates. Nothing is saved | |
| until you review and press Save. Item files are never retained on the server.</li> | |
| </ol> | |
| <h3 id="ai-draft">Custom construct, drafted with AI (new)</h3> | |
| <p>For constructs with no validated questionnaire: the platform can draft candidate | |
| items from the construct's name and a short explanation. The draft is a starting | |
| point, <b>not</b> a validated scale - you review, edit, and delete before saving, and | |
| everything the construct touches is labeled "AI-generated · not validated". | |
| Signed-in users only, 20 drafts/day.</p> | |
| <ol> | |
| <li><b>Happy path:</b> sign in > "+ New construct" > the "Draft with AI" | |
| tab. Name: <code>Digital overwhelm</code>. Description: <i>"Feeling that | |
| screens, notifications, and online demands exceed one's capacity to keep | |
| up."</i> Press "Draft items". Expect in a few seconds: ~10 first-person, | |
| positively-worded items in the textarea (no <code>(R)</code> items - by | |
| design), a "0 of 20 used today" style counter, an amber "AI-generated · not | |
| validated - drafted by <model>" notice, and sometimes short model notes | |
| (e.g. which facets it covered).</li> | |
| <li><b>Review is the point:</b> edit one item, delete a weak one, then Save. | |
| The construct appears in the picker under "My custom constructs" with an | |
| <b>AI-generated · not validated</b> tag - the tag stays even though you | |
| edited, because the seed was AI (the item hash records your edits).</li> | |
| <li><b>Library guardrail:</b> on the same tab, type <code>Satisfaction with | |
| Life</code> as the name. Expect a warning that the library already has this | |
| scale with validated items - use that instead of generating.</li> | |
| <li><b>It follows your definition:</b> draft the same name twice with two | |
| different descriptions (e.g. define "resilience" once as bouncing back from | |
| setbacks, once as tolerating discomfort). The items should track YOUR | |
| wording, not a generic textbook version - that is the feature working.</li> | |
| <li><b>Vague input:</b> give a nonsense name (<code>Zorblex</code>) with a vague | |
| description. Expect items anyway, plus model notes explaining it could not | |
| identify a standard construct - refine the description and redraft.</li> | |
| <li><b>Run + provenance:</b> run any corpus against your saved AI construct. | |
| The results page shows a caution line; the metadata JSON download has | |
| <code>source_type: "llm_generated"</code>, the drafting model + prompt | |
| version + date, and a machine-readable cautionary note. This travels into | |
| the reproduction script too.</li> | |
| <li><b>Signed out:</b> the "Draft with AI" tab shows a sign-in nudge instead of | |
| controls; the API refuses anonymous calls outright.</li> | |
| </ol> | |
| <div class="note">These items are drafted by an AI language model and have not been | |
| psychometrically validated. Where a validated scale exists, prefer it; interpret | |
| scores from AI-drafted constructs with appropriate caution. (Validation study - | |
| AI-drafted vs. validated SWLS/MFQ items on the same texts - is planned before | |
| public launch.)</div> | |
| <h2 id="warnings">4. Language, models, and warnings (Step 3 card + results)</h2> | |
| <p>Run each of these and open the results page; the amber warnings panel should show exactly:</p> | |
| <div class="tablewrap"> | |
| <table> | |
| <tr><th>Corpus</th><th>Selection</th><th>Expected warnings</th></tr> | |
| <tr><td><a href="/samples/warnings_showcase.csv" download>warnings_showcase.csv</a></td><td>en + MiniLM</td> | |
| <td>EMPTY_ROWS_DROPPED (2), DUPLICATE_TEXTS (2), TEXT_TOO_SHORT (3), TEXTS_MAYBE_TRUNCATED (2); no language warnings</td></tr> | |
| <tr><td><a href="/samples/french_demo.csv" download>french_demo.csv</a></td><td>en + MiniLM</td><td>LANGUAGE_MISMATCH (detected fr, 100%)</td></tr> | |
| <tr><td>french_demo.csv</td><td>fr + MiniLM</td><td>MODEL_LANGUAGE_UNSUPPORTED</td></tr> | |
| <tr><td>french_demo.csv</td><td>fr + Multilingual E5</td><td>no language warnings</td></tr> | |
| <tr><td><a href="/samples/mixed_language_demo.csv" download>mixed_language_demo.csv</a></td><td>en + MiniLM</td><td>LANGUAGE_UNCERTAIN (majority 50%)</td></tr> | |
| <tr><td><a href="/samples/long_documents_demo.csv" download>long_documents_demo.csv</a></td><td>en + MiniLM</td> | |
| <td>TEXTS_MAYBE_TRUNCATED (4) + LANGUAGE_UNCERTAIN (only 10 rows, below the 20-row minimum - by design)</td></tr> | |
| </table> | |
| </div> | |
| <p>Warnings are per-run snapshots: changing language/model requires a NEW run; old result | |
| pages don't update.</p> | |
| <h2 id="results">5. Results and reproducibility</h2> | |
| <ol> | |
| <li>Run <a href="/samples/moral_foundations_demo.csv" download>moral_foundations_demo.csv</a> | |
| against two different MFQ-2 foundations (separately, or both in one | |
| multi-construct run): top texts change per foundation; the 6 | |
| neutral rows sink to the bottom.</li> | |
| <li>Results page: histogram, mean/SD/min/max, per-item loadings, top/bottom texts; | |
| multi-construct runs add the correlation matrix up top.</li> | |
| <li>Downloads: results CSV (input columns + sim_item_N + ccr_score; multi-construct | |
| runs prefix these per construct), metadata JSON | |
| (model revision, construct snapshot + item hash, language block, environment pins), | |
| reproduction script + requirements file.</li> | |
| <li>Reproduction check: both downloads carry your run's id, e.g. | |
| <code>pip install -r requirements-repro_<run-id>.txt</code>, then | |
| <code>python reproduce_analysis_<run-id>.py your_corpus.csv</code> on a machine | |
| with no platform access; the exact commands (with your run id and CSV name) are in | |
| the script's header. Values should match the export (target ~1e-5 with real models).</li> | |
| </ol> | |
| <h2 id="accounts">6. Accounts</h2> | |
| <ol> | |
| <li>Sign in (top right) > "Create a free account" > email + password (min 8 chars) - | |
| or use "Continue with Google".</li> | |
| <li>You're signed in immediately; the header shows your name.</li> | |
| <li>Sign out, sign back in; wrong password gives "Incorrect email or password"; | |
| registering the same email again gives "already exists".</li> | |
| <li>Email is case-insensitive. No self-service password reset yet - reset = admin action. | |
| (Accounts persist across restarts now - no need to re-register.)</li> | |
| </ol> | |
| <h2 id="anon">7. Anonymous tiers (test signed OUT)</h2> | |
| <ol> | |
| <li>Upload caps: see section 2.</li> | |
| <li>Run limit: run 3 analyses. The Step 3 card counts "X of 3 free runs used today". | |
| The 4th run is refused with a sign-in prompt. Counter resets next day (UTC). | |
| Signing in removes the limit.</li> | |
| <li>Delete-after-analysis: run any corpus, open results (fine, downloadable), note the | |
| info warning "uploaded file was deleted after this analysis". Re-running that same | |
| corpus: refused ("upload again, or sign in").</li> | |
| <li>TTL purge: anonymous projects older than 24 h are deleted entirely (startup + hourly).</li> | |
| </ol> | |
| <h2 id="signedin">8. Signed-in tier</h2> | |
| <ol> | |
| <li>Sign in, upload, run: no ANONYMOUS_DATA_REMOVED warning; re-running the same corpus | |
| works (file kept).</li> | |
| <li>Saved-run budget: the Step 3 card shows "N of M saved runs used". Lab members and | |
| above have no cap; external accounts get 15. At the cap, new runs are refused until | |
| you delete old runs/projects (nothing is auto-deleted).</li> | |
| <li>Ownership: your projects are invisible to signed-out visitors and other accounts. | |
| Anonymous projects stay shared.</li> | |
| </ol> | |
| <h2 id="perf">9. Performance behaviors</h2> | |
| <ol> | |
| <li>Corpus-embedding cache: run the SAME corpus with a second construct (signed in, same | |
| model): the run skips document embedding and completes in seconds; metadata shows | |
| <code>"doc_embeddings_from_cache": true</code>.</li> | |
| <li>Duplicate texts are embedded once | |
| (<a href="/samples/warnings_showcase.csv" download>warnings_showcase.csv</a> has 2 | |
| dupes): identical scores for identical texts, less compute.</li> | |
| </ol> | |
| <h2 id="architecture">10. Under the hood</h2> | |
| <p>Architecture, data flow, data retention, and the full access/roles model | |
| (tiers, invite links, pre-assigned roles, audit trail) live on their own page: | |
| <a href="/product"><b>Product & Architecture →</b></a>. This guide stays | |
| focused on using and testing the platform.</p> | |
| <h2 id="feedback">11. Found something off?</h2> | |
| <p>Anything that doesn't match what this guide says it should do - or anything confusing, | |
| slow, or missing - post it in the lab's <b>#ccr Slack channel</b>: the 🐞 thread for bugs, | |
| the 💡 thread for ideas and feature requests. One line is enough; note the section number | |
| and what you saw; screenshots help. DMs to Deva work too, and email as a fallback | |
| (<a href="mailto:devaanand@umass.edu">devaanand@umass.edu</a>). Nothing is too small - | |
| "this button confused me" is exactly the kind of report we want.</p> | |
| </main> | |
| <a class="top" href="#">↑ Top</a> | |
| <div class="toast" id="toast" role="status" aria-live="polite">Link copied</div> | |
| <script> | |
| (function () { | |
| var toast = document.getElementById('toast'), timer; | |
| function ping(msg) { | |
| toast.textContent = msg; | |
| toast.classList.add('show'); | |
| clearTimeout(timer); | |
| timer = setTimeout(function () { toast.classList.remove('show'); }, 1600); | |
| } | |
| function share(id) { | |
| // location.hash also makes the browser scroll to and :target-flash the section. | |
| if (history.replaceState) history.replaceState(null, '', '#' + id); | |
| location.hash = id; | |
| var url = location.href; | |
| if (navigator.clipboard && navigator.clipboard.writeText) { | |
| navigator.clipboard.writeText(url).then( | |
| function () { ping('Section link copied'); }, | |
| function () { ping('Link in address bar'); } | |
| ); | |
| } else { | |
| ping('Link in address bar'); | |
| } | |
| } | |
| // Give every id'd heading a click-to-copy "#" affordance. | |
| var heads = document.querySelectorAll('h2[id], h3[id]'); | |
| Array.prototype.forEach.call(heads, function (h) { | |
| var a = document.createElement('a'); | |
| a.className = 'anchor'; | |
| a.href = '#' + h.id; | |
| a.textContent = '#'; | |
| a.setAttribute('aria-label', 'Copy link to this section'); | |
| a.addEventListener('click', function (e) { e.preventDefault(); share(h.id); }); | |
| h.appendChild(a); | |
| // Clicking the heading text itself (not a link inside it) also shares. | |
| h.style.cursor = 'pointer'; | |
| h.addEventListener('click', function (e) { | |
| if (e.target.tagName === 'A') return; // let real links behave normally | |
| share(h.id); | |
| }); | |
| }); | |
| })(); | |
| </script> | |
| <script> | |
| // Mirror the app header: the internal "How it works" link only shows for | |
| // lab members and above (the server gates /product regardless). | |
| fetch("/api/auth/me").then((r) => r.json()).then((me) => { | |
| if (["lab", "maintainer", "pi"].includes(me.role)) { | |
| document.getElementById("nav-product").hidden = false; | |
| } | |
| }).catch(() => {}); | |
| </script> | |
| </body> | |
| </html> | |