SpiralScout statistical analysis — upload or select data sources, run agent-assisted R analysis, and review persisted reports, plots, artifacts, and realtime progress.

BUSL-1.1 163 downloads
Updated 4 days ago Repository
kicksidestatisticsanalysisagentsr

Run

wippy run spiralscout/stat-analysis

spiralscout.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 canonical kickside.core thread (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, worker func://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_data exposes that same package-owned staging and exchange path as a strict kickside.block/v1 wait Block; it resumes through kickside.blocks:resume without 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.