Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Commit History
-
fix(storage): do not require server-side copy for example corpora
Loading the full CAMEL corpus 500'd on the lab's deployment. The cause is not ours: R2 CopyObject is unavailable on that bucket, answering NoSuchKey for an object head_object resolves in the same session and with both CopySource forms. The dev account copies the identical 38 MB file without complaint, so this varies by account and cannot be relied on. The server-side copy was only ever an optimisation - it avoids reading 38 MB back out through the app per visitor. The caller has already downloaded the file to parse it, so the fallback is to upload that local copy: one upload, no extra fetch, and it works on any S3-compatible backend. Verified against the lab's bucket, where it now succeeds and leaves the master object intact. Note for whoever adds the next deployment: dev and prod are separate Cloudflare accounts, so the master file needs uploading once per account with scripts/upload_example_corpus.py. The catalogue only stores the key. Co-Authored-By: Claude Opus 5 (1M context) <n…82c5ea2 -
fix(ui): sample data picker is a dropdown with an info button
Choosing which corpus to run is a choice between mutually exclusive options, so it is a dropdown rather than a stack of rows: adding a dataset later costs one more option instead of another block of Step 1, and the panel stays one line tall whatever the catalogue holds. The per-entry About link becomes a single circular info button sized to the other controls, so it reads as part of the row rather than a glyph dropped into it. The dialog it opens now carries the CAMEL mark beside the name; the logo belongs there, on the dataset being described, and not in the picker, which lists several corpora and would imply they share a source. The selected entry keeps its one-line summary under the row, and an entry this instance cannot run is disabled in the dropdown, labelled "unavailable here", with the reason underneath. Drops the now-unused .samples-list, .sample-row, .sample-text, .sample-name, .sample-meta and .sample-actions rules rather than leaving them behind. Co-Authored-By: Claude …69aff04 -
fix(ui): sample data as a small entry point under the upload row
The PI's framing for CAMEL is a small "use sample data" call to action: from it a visitor sees the two available sizes, and can read about the data if they want to. The dropdown row did the opposite - it sat above the upload control and read as the first thing to do. Step 1 is now upload first. Under the row, one muted line ("No data of your own? Use sample data") expands in place into a two-row list: name, size, language, a one-line fit note, About, Use. About opens the provenance dialog (description, text column, preprocessing, citation, dataset link), which carries its own Use button so a reader can decide from there; Escape and the backdrop close it. The panel closes once a corpus is loaded, and the Corpus select echoes the sample's name rather than its filename. Sizes an instance cannot run stay listed with the reason and a disabled Use. Picking a size already in the project selects that copy instead of copying the corpus again, so a second click cannot duplicate 38 MB in the bu…0b5c981 -
fix(ui): one compact corpus row instead of two large cards
Three problems with the first cut, all fair. CAMEL appeared twice, as two "corpora". It is one dataset in two sizes, so the sizes are now options in a single dropdown and it reads as one dataset. It was badged DEFAULT, which overstates it. The PI asked for CAMEL to be "available and ready-to-use"; that is a starting point, not a claim that this is THE corpus. The field is renamed default -> preselected, it decides ordering and what loads first, and nothing is badged. The two expanded cards took most of Step 1 and pushed the upload control below the fold, which is the wrong hierarchy: most researchers bring their own data. Step 1 is now one labelled row - dropdown, info button, action - and the provenance (description, text column, preprocessing, citation, dataset link) moved into a modal behind the info button, where it is one click away without occupying the step. Also: the listing now knows this instance's row ceiling. The full corpus is 57,174 rows against a deployed CCR_MAX_ROW…bb4c28d -
fix(anon): owner key overflowed owner_user_id, 500ing anonymous writes
Live outage on both deployments since spec 0009 shipped on 2026-09-04: POST /api/projects and POST /api/constructs returned 500 for anyone not signed in, which is the entire anonymous try-it path. ANON_PREFIX + secrets.token_hex(16) is 37 characters and both owner_user_id columns are String(32). SQLite ignores VARCHAR limits so all 162 tests passed locally; PostgreSQL enforces them, so every anonymous insert was rejected. Signed-in users were unaffected because a user id is exactly 32 characters, which is why nobody reported it - lab members are signed in. Shortened the session id to 13 bytes (104 bits of entropy, key length 31) rather than widening the column. A type change is not additive, so auto_migrate_sqlite would not apply it and both deployed databases would have needed hand-run DDL; this deploys as-is. No data is lost because no anon: row was ever successfully written. The regression test reads the column width from the model rather than hardcoding it, and asserts against t…a7f2409 -
feat(corpus): offer the full CAMEL corpus from R2, raise the row ceiling
Follows spec 0010, which shipped only a 999-text sample because the full corpus could not be ingested. CCR_MAX_ROWS goes to 100,000, which was the code default all along; the three docs that variously claimed 20,000 and 50,000 are corrected to agree with it and with each other. That removes the ceiling that made the 57,174-row corpus un-ingestible. The full corpus is served from R2 under examples/, not the repo: 38 MB would ride in the Docker image and the Space repo on every deploy. It is deliberately NOT fetched from Hugging Face at runtime - that dataset returns 401, so fetching it would mean shipping lab credentials in a public app. scripts/upload_example_corpus.py puts it there and prints the row count the catalogue entry has to declare. Selection downloads the master once to parse, then makes the user's copy with a server-side copy_object, so 38 MB does not travel back out through the application for every visitor. Verified against the live bucket: 7.0s fetch, 0.7s parse of 57…88b1ea9 -
feat(corpus): CAMEL as a built-in example corpus [spec 0010]
PI request from 2026-08-19: make the lab's CAMEL corpus the example data on the site so visitors can try CCR without uploading anything. Corpus details from Aliah 2026-09-06. Step 1 now offers an example corpus above the upload control. One click loads it, selects the declared text column, and the run proceeds through the normal ingest path, so nothing downstream changes. The citation and a link to the full dataset sit on the card, and a run on an example writes a corpus_source block into its metadata carrying the citation, source URL and preprocessing note: results produced on someone else's corpus have to stay attributable in the same file as the scores. Ships a 999-text SAMPLE rather than the full corpus, because the full one cannot be the bundled default: 57,174 rows exceeds CCR_MAX_ROWS (50,000 on both deployments) so ingest would refuse it outright, 38 MB against a 156 KB sample_data would ride in the Docker image and the Space repo, and a demo has to finish in seconds on 2 vCP…3a1d713
-
feat(privacy): anonymous session scope, construct TTL, creation cap [spec 0009]
Follows spec 0008, which scoped custom constructs to signed-in owners and left the anonymous tier as one shared bucket. Digging into that surfaced that three separate defects were being read as one "constructs are public" bug. No anonymous identity: owner_user_id == "" meant anonymous, so every anonymous visitor shared a bucket and saw everyone else's projects and constructs. Anonymous visitors now carry a signed session-id cookie and own their rows as "anon:<id>", so one column carries both ownership kinds and the shared bucket is retired for projects and constructs at once. Signing in ADOPTS that session's rows into the account: without it, scoping anonymous work to a session would strand it at sign-in, and it also replaces the reason 049074a left anonymous projects open to everybody. No lifecycle: retention.py imported Corpus, Job, Project - Construct was not in it, and constructs hang off no project, so nothing ever cascaded to them. Corpora go when a run finishes and projects ex…b35131c -
fix(privacy): scope custom constructs to their creator, add delete [spec 0008]
A PhD student reported seeing custom constructs on the public site that they had not created, with no way to remove them. Construct had no owner column at all, so every custom construct anyone typed was returned to every visitor by GET /api/constructs - listed, with some irony, under a picker heading reading "My custom constructs". This is the projects listing leak (049074a) one table over: that fix taught _visible_owners the right rule, but constructs had no ownership concept to correct. Construct gains owner_user_id, mirroring Project, and the listing applies the same rule: seeds are public, a signed-in user sees only their own custom constructs, anonymous ones stay in the shared anonymous bucket. Both columns are additive with scalar defaults, so auto_migrate_sqlite adds them to the deployed databases and existing constructs become anonymous - which removes them from every signed-in user's picker on upgrade, without a manual cleanup. Deletion is a confirmation dialog in the picker…3594eb6
-
fix(constructs): resolve the review's open questions from Noor's answers
She replied with the source she used for each disputed item, and every one checks out. Three of the four disagreements were about which PRINTING of a scale is authoritative, not about who read it correctly. MFQ Fairness: I was wrong to revert her. She read the questionnaire printed at the end of Graham et al. (2011), which is the paper this construct cites, and it does say "treated differently from others" (twice). The moralfoundations.org MFQ30 handout says "than others". Her correction is applied and source_url now points at the paper, so items, citation, and source finally agree. RSES and CBI work-related burnout: she used the source_url recorded on each construct, and both mappings are exactly right against it. The Rosenberg questionnaire at socy.umd.edu starts with "I feel that I'm a person of worth" and its wording and reverse keys match ours item for item, so only our ORDER was wrong. Both are reordered to the printed order with item ids renumbered, so item_id means "source it…0af19f8 -
fix(constructs): verify MFQ against the source the review sheet omitted
Checking whether the follow-up questions for the reviewer were fair turned up that two of them were not. The review sheet shipped with an EMPTY source_url for mfq_care and mfq_fairness, so the reviewer had nothing to check those against and correctly flagged it. That was our omission, not a missing document: the MFQ30 is public, all four items in each construct match it verbatim, and both are now verified with the source recorded. This also settles the "differently than/from others" disagreement in favour of the wording already stored. Also confirmed independently, so the reviewer does not need to be asked: the Subjective Happiness Scale PDF at the source_url we gave her does read "Compared to most of my peers", exactly as she corrected it. And for context on the two item-order findings: the APA measures-package printing of the RSES numbers its items exactly as we store them, while the reviewer's renumbering matches another widely-used printing. Same version-mismatch pattern as Edmo…10425ec -
fix(constructs): correct the review pass after a validity review
A research-validity review of the previous commit found four real problems. All four are fixed here. Two of the reviewer's wording corrections moved an item AWAY from the publication its construct cites, and I had applied them under a `verified` badge. Checked against the sources: the published MFQ30 reads "treated differently than others" (not "from"), and Edmondson (1999) reads "It is safe to take a risk on this team" (not "in") - the proposed "in this team" comes from a third-party questionnaire, whose URL I had also promoted over the working Edmondson PDF. Both items keep their published wording, both constructs are held back as unverified with the disagreement recorded, and the source_url override is dropped. The reviewer's item-ORDER findings for rses and cbi_work_related_burnout were silently dropped: my classifier only read notes on rows that failed one of the four checks, and these sat on rows marked OK. Order feeds item_hash and decides what sim_item_N means, so both are no…461b859 -
feat(constructs): apply the 2026-08-25 library review [spec 0007]
Noor Skhiri reviewed all 525 items across the 94 constructs (wording, reverse keying, subscale grouping, citations). This applies it. Split by what item_hash covers. Item changes ship as a NEW version: 61 reverse-scoring flags corrected across 14 constructs (35 -> 96 flagged items), 9 verbatim wording fixes, and one SCS-SF item moved to Over-identification per the source coding key. 23 constructs gain a version 2; their version 1 files keep their original items and are marked archived so runs that pinned them still resolve. Everything outside the hash is edited in place: 88 constructs promoted to verified with reviewer and date recorded, plus citation and source_url repairs. Six constructs stay needs_verification pending two PI decisions (the IPIP "I" prefix and the K10 stem). Two loader gaps had to close for this to ship: sync_library was insert-only, so a status change could never reach an already-seeded database, and the picker listed every version, so a v2 would show the same co…4afd259
-
feat(scoring): anchor vectors (bipolar constructs) [spec 0006]
Score texts along the axis between a target construct and a contrasting "opposite" construct: AV = target_centroid - opposite_centroid, anchor score = cosine(text, AV) (default) or dot(text, AV). Because embeddings are L2-normalized, a pole's CCR score (mean of per-item cosines) equals text . centroid, so the dot score is exactly target_score - opposite_score and the export is self-checking. - engine: run_ccr_anchored() (per-pole sims/scores + anchor score + metadata), reuses the doc-embedding cache; degenerate poles flagged. - data model: Job.opposite_construct_id + similarity_metric (additive columns). - runner: anchored export columns under output_schema_version 1.2, bipolar summary, both construct snapshots + scoring block in metadata, ANCHOR_DEGENERATE_POLES warning. - API: POST /api/jobs opposite_construct_id + similarity_metric, validated (single target, distinct poles, cosine|dot); JobOut echoes anchored fields. - reproduction script: anchored variant embeds both item …f341328
-
Apply PI decisions: anon row cap 200, drop CRS, RA verification checklist
Anonymous row cap 500 -> 200 (anonymous tier only; signed-in research needs thousands of rows - scoping recorded in DECISIONS.md). CRS removed from the library (5 dimension files; PI decision, citation was missing). docs/verification_checklist.csv: 525 items / 94 constructs, one row per item with RA correction columns. Library items approved for public repos by the PI (rights question resolved).ffae73c
-
feat: upload tiers with placeholder sign-in, project archive/delete, no-em-dash rule
- Anonymous caps (2 MB / 500 rows, env-tunable) with sign-in hints; demo name-only session (HMAC cookie) lifts caps; get_current_user() is the Phase 2 swap point for managed auth - Archive/unarchive projects (reversible, Archived sidebar group) - Permanent delete with typed-name confirmation; cascades datasets, runs, uploaded + result files; logged without retaining text (design par. 9) - Fix: job executor recreates after lifespan shutdown (dev reload broke jobs) - Style: em dashes removed across 50 files; rule in CLAUDE.md + edit hook - Tests: 39 total (tiers, tampered cookie, archive toggle, delete cascades)e7712a6 -
feat: Phase 0 features — warnings, language, registry, library, script export (specs 0001-0004)
- Structured warning objects incl. TEXT_TOO_SHORT, LANGUAGE_MISMATCH/UNCERTAIN, MODEL_LANGUAGE_UNSUPPORTED (registry-resolved language sets), MODEL_NOTE - Corpus-level language detection (langdetect, seeded/deterministic; recorded in metadata) - Model registry wired end-to-end: dropdown, validation, E5 'query: ' prefixes on items+texts, pinned-revision support, MiniLM default - Construct library from versioned YAML with reference item-hash implementation, append-only sync, verification status in UI, reverse-scored flags stored - Reproduction script + pinned requirements export (offline-runnable, no platform deps) - Metadata: output_schema_version, scoring block, construct snapshot, environment pins - Ingestion fix: delimiter detection restricted to , ; tab | (single-column space bug) - Tests 17 -> 32; spec statuses + deviations recorded; CHANGELOG 0.2.01217b19 -
Initialize CCR Platform mainline (Culture and Morality Lab)
Seeded from the public demo (Deva-1903/ccr-platform), which stays deployed. Adds the control system around it: - CLAUDE.md + path-scoped rules (.claude/rules/) encoding design-doc §15 architecture rules - 3 review agents (research-validity, test-parity, docs-sync) - 4 commands (/implement-spec, /review-scoring-contract, /run-checks, /log-decision) - Hooks: golden-output protection (PreToolUse block), Python syntax check (PostToolUse) - packages/model_registry: models.yaml (MiniLM default, e5-large-v2, multilingual-E5 with prefix usage_config) + language sets + working validator - packages/construct_library: 5 versioned construct YAMLs + item-hash validator - docs/specs 0001-0005 (Phase 0/1 work), design doc v1.2, DECISIONS/ROADMAP/CHANGELOG - evals/ scaffold with protected expected_outputs Design of record: docs/design/CCR_Platform_Design_Doc_v1.2.docx4d86d33