factcircuit
FactCircuit: an auditable claim-and-evidence verification loop with immutable provenance, staged checks, bounded retrieval, and reproducible evaluation.
SafeStat — microdata.no emulator with protected/encrypted sources, restricted execution and remote analysis. Sister project of OpenStat.
DataPython · JavaScriptGitHub @hmelbergOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Sister projects: OpenStat — the open, simplified edition (no login, no protected/encrypted sources, no remote execution, BYOK-only AI) — and Microdata — the dedicated microdata.no emulator (persona locked on, UI tracking microdata.no; cloned from openstat 2026-07-10 with full git history, so
git cherry-pickworks across the repos). The engine (m2py.py) is the source of truth here; fixes land in SafeStat first and are ported to the siblings.
A browser app for running statistics scripts in several languages — microdata,
Python, R, DuckDB, Brython, jamovi, Statx, SafeStat (remote) — with the
microdata language powered by an engine that emulates
microdata.no: it translates microdata scripts to Python
and runs them in the browser via Pyodide, and generates synthetic register data
from metadata. Around it: Python/R runners, Python/R → microdata translators,
a step-by-step tutorial mode, and AI features (code generation, a
data-minimization/privacy review, and result interpretation). Microdata is an
ordinary mode here (its special UI shows only while microdata mode is active);
the always-on emulator experience lives in the microdata sibling repo. The
default mode is chosen per subdomain (js/notebook-links.js hostnameMode()),
with python as the fallback.
| Path | What |
|---|---|
index.html | The front-end app shell (editor, runners, mode system, settings) + remaining inline modules. |
app.css, js/ | Extracted front-end: app.css (styles); js/login.js, js/ai-chat.js, js/github-storage.js (classic <script src> modules loaded after the inline block, sharing the window.* surface). |
m2py.py | The interpreter: MicroParser + MicroInterpreter (engine, mock-data, stats, disclosure control). Source of truth — the microdata-api copy is generated. |
functions.py | microdata functions used in generate/replace/if expressions. |
protect.py | scrub-* data-protection verbs (noise, swap, k-anon, risk, …). |
mockdata_export.py, static_source.py, build_static_data.py | Static synthetic-data build (Parquet/DuckDB) + the static data source. |
netlify/edge-functions/ | The AI endpoints (dm-vurder, kode-svar, tolk-resultat) + shared _lib/. |
manual_scripts/ | End-to-end example scripts run as a smoke suite. |
tests/ | pytest suite (engine, regressions, equivalence, mock-data, performance). |
A companion repo, microdata-api (Anvil), hosts the auth/AI backend and a
generated copy of the engine — see Syncing the engine below.
# Set up the Python environment (once)
python3 -m venv .venv && .venv/bin/python -m pip install -r requirements.txt
# Python tests (engine, regressions, equivalence, mock-data)
.venv/bin/python -m pytest tests/
# End-to-end smoke suite (exits non-zero on any CRASH/PARTIAL)
.venv/bin/python manual_scripts/run_manual_scripts.py
# Translator tests
# Edge functions (Deno)
cd netlify/edge-functions && deno check *.ts _lib/*.ts && deno test --allow-all _lib/
# Build the static synthetic dataset (writes static_data/*.parquet + manifest.json)
.venv/bin/python build_static_data.py --persons 100000 --from 2015 --to 2023
# Propagate the engine to the microdata-api (Anvil) copy
.venv/bin/python sync_to_api.py --apply # copy; without --apply it only reports drift
# Diff delte kjernefiler mot ../microdata (openstat-benet fjernet 2026-07-24 —
# openstat har ikke lenger motoren og er en selvstendig kodebase)
sh scripts/sync_check.sh # exit 1 ved avvik; UI-filer er bevisst utelatt
CI lives in .github/workflows/ (pytest + manual scripts, edge).
Built-in examples live in examples/<mode>/ — one folder per editor mode
(micropython/, microdata/, …), with an optional one level of NN_category/
subfolders (e.g. microdata/03_deskriptiv_statistikk/) that become categories
in the modal. Add or remove a file, then regenerate the manifest:
# Rebuild examples/manifest.json from the folder tree
.venv/bin/python examples/generate_manifest.py
The «Eksempler» button opens a mode-scoped modal built from
examples/manifest.json (fetched lazily the first time the modal opens — no
startup cost). Each example's label comes from a # label: <text> line in the
file (else #options.title, else the filename). No index.html edit is
needed to add or remove examples.
The site deploys on Netlify (netlify.toml): static files + the three edge
functions. sw.js precaches Pyodide — bump CACHE whenever the precache
list changes.
m2py.py and functions.py are the source of truth here. The copies in
microdata-api/server_code/ are generated — edit the engine here, then run
sync_to_api.py --apply. The copies carry a "GENERATED COPY — edit in m2py"
header; running sync_to_api.py without --apply reports drift (can gate CI).