stat-analysis
SpiralScout statistical analysis — upload or select data sources, run agent-assisted R analysis, and review persisted reports, plots, artifacts, and realtime progress.
Run
wippy run spiralscout/stat-analysisspiralscout.stat_analysis
Layered, conversational statistical experiments over real GNU R (WASM), on the canonical Kickside component/thread CQRS:
- a SPACE (
stat_analysis_kind) is the workspace component holding session files and experiments - an EXPERIMENT (
experiment_kind) is a child component under the space (parent_id linkage — ownership/ACL/sharing come from the component substrate) carrying ONE canonicalkickside.corethread (thread_id == component_id) - every user query opens an EXCHANGE on that thread:
events:query→ agent work (events:run_r,events:progress) →events:result|events:failed - the projection declared on
experiment_kind(meta.projections, workerfunc://spiralscout.stat_analysis:projection_worker) folds thread events into the module-owned read model; retention is drain-aware so events are never pruned ahead of the projection cursor - every append fans out on the thread realtime topics (
kickside.threads,kickside.thread.<id>); the UI subscribes and refetches — no polling - R continuity is deterministic: every RunR call restores and saves the
experiment's workspace image at
/data/.state/<experiment_id>.RData, so a follow-up starts exactly where the previous exchange left the R session - rendered plots return to the agent as visual content (
_images, base64 PNG), so the model inspects what it drew; ReadArtifact returns prior images the same way - the user's Depth slider maps to a per-exchange RunR iteration budget, enforced as a hard cap in the tool
block.analyze_dataexposes that same package-owned staging and exchange path as a strictkickside.block/v1wait Block; it resumes throughkickside.blocks:resumewithout importing visual Workflows
Read model (all tables owned by this module, app:db)
| Table | Key | Written by | Holds |
|---|---|---|---|
| spiralscout_stat_analysis_experiment | experiment_id (== thread/component id) | projection fold (repo.apply, events:query/result/failed) | space_id, thread_id, title, status, depth, exchange_count |
| spiralscout_stat_analysis_run | analysis_id (exchange id) | fold (events:query genesis, events:result/failed terminal) | experiment_id, seq, prompt, depth, status, report_md |
| spiralscout_stat_analysis_event | (analysis_id, thread seq) | fold (every exchange-correlated event) | the exchange timeline rows the UI renders |
| spiralscout_stat_analysis_artifact | artifact_id | RunR at creation + idempotent fold replay | kind, title, upload_id, raw_url, spec |
| spiralscout_stat_analysis_file | (component_id, upload_id) | files API | the space's session files |
Cleanup: deleting an experiment (component delete → deletable) removes its
exchanges, event rows, artifacts, and R state image; deleting a space deletes its
experiment children first (the substrate refuses parents with live children),
then sweeps session files and legacy rows. Migration 05 backfills every
pre-experiment run as a single-exchange legacy experiment (no thread; gated
through its space's ACL).
Verified R format matrix (live-probed; pinned by readers_live_test)
| Format | Reader | Verdict |
|---|---|---|
| .csv | read.csv | works |
| .tsv | read.delim | works |
| .rds | readRDS | works |
| .rda / .RData | load() | works |
| .xlsx / .xls | readxl::read_excel | works |
| .sav | haven::read_sav | works for uncompressed and classic bytecode-compressed SAV; numeric/string variables, variable/value labels, and system-missing values |
| .zsav | haven::read_sav | unsupported (zlib-compressed SAV) |
| .dta / .por | haven::read_dta/read_por | unsupported |
| .json | jsonlite | fails — jsonlite absent from the build |
SPSS strings over 255 bytes and SAV writing are unsupported. caret, NMF, and clustree are also stub packages (empty or stub-only exports).
Provisioning (wippy-langs/r >= 0.2.12): the module ships only the WASM reactor;
the R_HOME image (base + recommended + curated packages) is an EXTERNAL host
directory the app binds through the rhome_directory ns.dependency parameter
(here: kickside/app/.wippy/r-home). There is no bundled image and no download
command — the host-supplied tree is the one source of R packages. Starting with
wippy-langs/r 0.2.12, readxl is cross-compiled for Excel and haven supplies a
pure-R SPSS SAV reader. Re-verify on every image swap: the live reader tests use
real workbooks and SAV fixtures so the advertised format contract cannot drift.