Spaces:
Sleeping
Sleeping
File size: 28,673 Bytes
ed98758 4e87534 9fce59c ed98758 4e87534 ed98758 4e87534 ed98758 c53fa39 54bd1cf c53fa39 54bd1cf c53fa39 54bd1cf c53fa39 54bd1cf c53fa39 ed98758 d7891e4 46b1454 4e87534 46b1454 ed98758 54bd1cf 4e87534 6a6c7cf 54bd1cf 8586c1b c53fa39 54bd1cf ed98758 54bd1cf ed98758 9fce59c 8586c1b ed98758 0b29b70 ed98758 d7891e4 0b29b70 ed98758 b89016c b195b7b 069d95d b195b7b b89016c 329d800 bfb6467 329d800 bfb6467 329d800 bfb6467 329d800 bf6c4d6 329d800 ed98758 329d800 ed98758 b195b7b ed98758 069d95d ed98758 069d95d ed98758 9fce59c ed98758 9fce59c ed98758 bf6c4d6 069d95d bf6c4d6 ed98758 9fce59c ed98758 b195b7b ed98758 b195b7b ed98758 ffe862f ed98758 9fce59c ed98758 9fce59c 0b29b70 ed98758 bfb6467 ed98758 bfb6467 d7891e4 bfb6467 9fce59c b89016c ed98758 46b1454 c53fa39 ed98758 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 | <!doctype html>
<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>
|