robostats 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- robostats-0.1.0/.gitignore +27 -0
- robostats-0.1.0/CHANGELOG.md +82 -0
- robostats-0.1.0/CLAUDE.md +204 -0
- robostats-0.1.0/LICENSE +201 -0
- robostats-0.1.0/PKG-INFO +361 -0
- robostats-0.1.0/README.md +337 -0
- robostats-0.1.0/briefs/01-records-and-intervals.md +165 -0
- robostats-0.1.0/briefs/02-paired-comparison.md +197 -0
- robostats-0.1.0/briefs/03-coverage-validation.md +175 -0
- robostats-0.1.0/briefs/04-ingestion-and-reporting.md +195 -0
- robostats-0.1.0/briefs/05-relax-protocol-enforcement.md +180 -0
- robostats-0.1.0/briefs/06-nested-loading-and-join-provenance.md +170 -0
- robostats-0.1.0/briefs/07-presets-readers-recorders.md +209 -0
- robostats-0.1.0/briefs/08-recorder-provenance.md +151 -0
- robostats-0.1.0/briefs/09-align-and-alignment.md +211 -0
- robostats-0.1.0/briefs/10-overlap-diagnostic.md +195 -0
- robostats-0.1.0/briefs/11-unpaired-sensitivity-coherence.md +195 -0
- robostats-0.1.0/briefs/12-combined-and-auto.md +215 -0
- robostats-0.1.0/briefs/13-packaging-and-release.md +133 -0
- robostats-0.1.0/briefs/ticket-comparison-model-rework-2.md +207 -0
- robostats-0.1.0/docs/recording.md +330 -0
- robostats-0.1.0/pyproject.toml +67 -0
- robostats-0.1.0/results/.gitkeep +0 -0
- robostats-0.1.0/results/benchmark-output-survey.md +162 -0
- robostats-0.1.0/results/coherence/README.md +57 -0
- robostats-0.1.0/results/coherence/manifest.csv +15 -0
- robostats-0.1.0/results/coherence/paired-0.90.csv +922 -0
- robostats-0.1.0/results/coherence/paired-0.95.csv +814 -0
- robostats-0.1.0/results/coherence/paired-0.99.csv +585 -0
- robostats-0.1.0/results/coherence/summary.csv +13 -0
- robostats-0.1.0/results/coherence/unpaired-exact-0.90.csv +524 -0
- robostats-0.1.0/results/coherence/unpaired-exact-0.95.csv +478 -0
- robostats-0.1.0/results/coherence/unpaired-exact-0.99.csv +411 -0
- robostats-0.1.0/results/coherence/unpaired-score-0.90.csv +310 -0
- robostats-0.1.0/results/coherence/unpaired-score-0.95.csv +310 -0
- robostats-0.1.0/results/coherence/unpaired-score-0.99.csv +310 -0
- robostats-0.1.0/results/combined-coverage/README.md +64 -0
- robostats-0.1.0/results/combined-coverage/combined-2-5-5-0.90.csv +306 -0
- robostats-0.1.0/results/combined-coverage/combined-2-5-5-0.95.csv +306 -0
- robostats-0.1.0/results/combined-coverage/combined-2-5-5-0.99.csv +306 -0
- robostats-0.1.0/results/combined-coverage/combined-4-3-3-0.90.csv +306 -0
- robostats-0.1.0/results/combined-coverage/combined-4-3-3-0.95.csv +306 -0
- robostats-0.1.0/results/combined-coverage/combined-4-3-3-0.99.csv +306 -0
- robostats-0.1.0/results/combined-coverage/combined-5-4-2-0.90.csv +306 -0
- robostats-0.1.0/results/combined-coverage/combined-5-4-2-0.95.csv +306 -0
- robostats-0.1.0/results/combined-coverage/combined-5-4-2-0.99.csv +306 -0
- robostats-0.1.0/results/combined-coverage/combined-6-2-2-0.90.csv +306 -0
- robostats-0.1.0/results/combined-coverage/combined-6-2-2-0.95.csv +306 -0
- robostats-0.1.0/results/combined-coverage/combined-6-2-2-0.99.csv +306 -0
- robostats-0.1.0/results/combined-coverage/combined-8-1-1-0.90.csv +306 -0
- robostats-0.1.0/results/combined-coverage/combined-8-1-1-0.95.csv +306 -0
- robostats-0.1.0/results/combined-coverage/combined-8-1-1-0.99.csv +306 -0
- robostats-0.1.0/results/combined-coverage/manifest.csv +20 -0
- robostats-0.1.0/results/combined-coverage/summary.csv +20 -0
- robostats-0.1.0/results/coverage/README.md +192 -0
- robostats-0.1.0/results/coverage/agresti_coull-n10-0.90.csv +344 -0
- robostats-0.1.0/results/coverage/agresti_coull-n10-0.95.csv +344 -0
- robostats-0.1.0/results/coverage/agresti_coull-n10-0.99.csv +344 -0
- robostats-0.1.0/results/coverage/agresti_coull-n100-0.90.csv +344 -0
- robostats-0.1.0/results/coverage/agresti_coull-n100-0.95.csv +344 -0
- robostats-0.1.0/results/coverage/agresti_coull-n100-0.99.csv +344 -0
- robostats-0.1.0/results/coverage/agresti_coull-n20-0.90.csv +344 -0
- robostats-0.1.0/results/coverage/agresti_coull-n20-0.95.csv +344 -0
- robostats-0.1.0/results/coverage/agresti_coull-n20-0.99.csv +344 -0
- robostats-0.1.0/results/coverage/agresti_coull-n50-0.90-high-p.csv +294 -0
- robostats-0.1.0/results/coverage/agresti_coull-n50-0.90.csv +344 -0
- robostats-0.1.0/results/coverage/agresti_coull-n50-0.95-high-p.csv +294 -0
- robostats-0.1.0/results/coverage/agresti_coull-n50-0.95.csv +344 -0
- robostats-0.1.0/results/coverage/agresti_coull-n50-0.99-high-p.csv +294 -0
- robostats-0.1.0/results/coverage/agresti_coull-n50-0.99.csv +344 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n10-0.90.csv +344 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n10-0.95.csv +344 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n10-0.99.csv +344 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n100-0.90.csv +344 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n100-0.95.csv +344 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n100-0.99.csv +344 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n20-0.90.csv +344 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n20-0.95.csv +344 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n20-0.99.csv +344 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n50-0.90-high-p.csv +294 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n50-0.90.csv +344 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n50-0.95-high-p.csv +294 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n50-0.95.csv +344 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n50-0.99-high-p.csv +294 -0
- robostats-0.1.0/results/coverage/clopper_pearson-n50-0.99.csv +344 -0
- robostats-0.1.0/results/coverage/manifest.csv +57 -0
- robostats-0.1.0/results/coverage/tango-n10-0.90.csv +1789 -0
- robostats-0.1.0/results/coverage/tango-n10-0.95.csv +1789 -0
- robostats-0.1.0/results/coverage/tango-n10-0.99.csv +1789 -0
- robostats-0.1.0/results/coverage/tango-n20-0.90.csv +1789 -0
- robostats-0.1.0/results/coverage/tango-n20-0.95.csv +1789 -0
- robostats-0.1.0/results/coverage/tango-n20-0.99.csv +1789 -0
- robostats-0.1.0/results/coverage/wilson-n10-0.90.csv +344 -0
- robostats-0.1.0/results/coverage/wilson-n10-0.95.csv +344 -0
- robostats-0.1.0/results/coverage/wilson-n10-0.99.csv +344 -0
- robostats-0.1.0/results/coverage/wilson-n100-0.90.csv +344 -0
- robostats-0.1.0/results/coverage/wilson-n100-0.95.csv +344 -0
- robostats-0.1.0/results/coverage/wilson-n100-0.99.csv +344 -0
- robostats-0.1.0/results/coverage/wilson-n20-0.90.csv +344 -0
- robostats-0.1.0/results/coverage/wilson-n20-0.95.csv +344 -0
- robostats-0.1.0/results/coverage/wilson-n20-0.99.csv +344 -0
- robostats-0.1.0/results/coverage/wilson-n50-0.90-high-p.csv +294 -0
- robostats-0.1.0/results/coverage/wilson-n50-0.90.csv +344 -0
- robostats-0.1.0/results/coverage/wilson-n50-0.95-high-p.csv +294 -0
- robostats-0.1.0/results/coverage/wilson-n50-0.95.csv +344 -0
- robostats-0.1.0/results/coverage/wilson-n50-0.99-high-p.csv +294 -0
- robostats-0.1.0/results/coverage/wilson-n50-0.99.csv +344 -0
- robostats-0.1.0/results/design-alignment-and-k-model.md +184 -0
- robostats-0.1.0/results/partial-overlap/README.md +361 -0
- robostats-0.1.0/results/partial-overlap/auto-level.csv +378 -0
- robostats-0.1.0/results/partial-overlap/free-grid.csv +232 -0
- robostats-0.1.0/results/partial-overlap/manifest.csv +10 -0
- robostats-0.1.0/results/partial-overlap/mask-level.csv +172 -0
- robostats-0.1.0/results/partial-overlap/power.csv +481 -0
- robostats-0.1.0/results/partial-overlap/summary.csv +18 -0
- robostats-0.1.0/results/partial-overlap/threshold.csv +17 -0
- robostats-0.1.0/results/statsmodels-mcnemar-m0.md +103 -0
- robostats-0.1.0/results/ticket-comparison-model-rework-2.md +207 -0
- robostats-0.1.0/results/ticket-comparison-model-rework.md +253 -0
- robostats-0.1.0/src/robostats/__init__.py +115 -0
- robostats-0.1.0/src/robostats/adapters/__init__.py +13 -0
- robostats-0.1.0/src/robostats/adapters/robodojo.py +109 -0
- robostats-0.1.0/src/robostats/adapters/robotwin.py +78 -0
- robostats-0.1.0/src/robostats/compare.py +2167 -0
- robostats-0.1.0/src/robostats/errors.py +96 -0
- robostats-0.1.0/src/robostats/intervals.py +238 -0
- robostats-0.1.0/src/robostats/io.py +1018 -0
- robostats-0.1.0/src/robostats/overlap.py +273 -0
- robostats-0.1.0/src/robostats/presets.py +399 -0
- robostats-0.1.0/src/robostats/py.typed +0 -0
- robostats-0.1.0/src/robostats/recording.py +299 -0
- robostats-0.1.0/src/robostats/records.py +1032 -0
- robostats-0.1.0/src/robostats/report.py +729 -0
- robostats-0.1.0/tests/test_adapters_robodojo.py +209 -0
- robostats-0.1.0/tests/test_alignment.py +598 -0
- robostats-0.1.0/tests/test_auto.py +204 -0
- robostats-0.1.0/tests/test_coherence.py +168 -0
- robostats-0.1.0/tests/test_combined.py +892 -0
- robostats-0.1.0/tests/test_compare.py +933 -0
- robostats-0.1.0/tests/test_coverage.py +498 -0
- robostats-0.1.0/tests/test_intervals.py +294 -0
- robostats-0.1.0/tests/test_io.py +1209 -0
- robostats-0.1.0/tests/test_overlap.py +449 -0
- robostats-0.1.0/tests/test_presets.py +342 -0
- robostats-0.1.0/tests/test_recording.py +621 -0
- robostats-0.1.0/tests/test_records.py +684 -0
- robostats-0.1.0/tests/test_report.py +513 -0
- robostats-0.1.0/tests/test_unpaired.py +719 -0
- robostats-0.1.0/validation/.gitkeep +0 -0
- robostats-0.1.0/validation/coherence.py +470 -0
- robostats-0.1.0/validation/combined_coverage.py +511 -0
- robostats-0.1.0/validation/coverage.py +1132 -0
- robostats-0.1.0/validation/partial_overlap.py +1758 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv
|
|
11
|
+
.venv/
|
|
12
|
+
__pycache__/
|
|
13
|
+
|
|
14
|
+
# Full-resolution coverage curves: regenerate with `uv run python validation/coverage.py`.
|
|
15
|
+
# The committed downsamples and manifest.csv under results/coverage/ are the checkable record.
|
|
16
|
+
results/coverage/full/
|
|
17
|
+
|
|
18
|
+
# Full-resolution coherence tables: regenerate with `uv run python validation/coherence.py`.
|
|
19
|
+
results/coherence/full/
|
|
20
|
+
|
|
21
|
+
# Full-resolution partial-overlap tables: regenerate with
|
|
22
|
+
# `uv run python validation/partial_overlap.py`.
|
|
23
|
+
results/partial-overlap/full/
|
|
24
|
+
|
|
25
|
+
# Full-resolution combined-coverage tables: regenerate with
|
|
26
|
+
# `uv run python validation/combined_coverage.py`.
|
|
27
|
+
results/combined-coverage/full/
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
First release. `robostats` reads episode-level records from a policy evaluation
|
|
6
|
+
and returns what the reported success rate actually supports: an interval, a
|
|
7
|
+
comparison against another policy, and a report saying what each run declared
|
|
8
|
+
about how it was collected.
|
|
9
|
+
|
|
10
|
+
### Two things to know that the API does not tell you
|
|
11
|
+
|
|
12
|
+
**`mode="combined"` has weak coverage over a handful of shared scenarios.** It
|
|
13
|
+
inverts an asymptotic statistic, and exact enumeration over 2 to 8 shared
|
|
14
|
+
scenarios puts its worst coverage at 0.757 against a nominal 0.90, 0.850 against
|
|
15
|
+
0.95 and 0.961 against 0.99, with the worst cases at cell configurations where
|
|
16
|
+
one outcome has no probability at all. Mean coverage over the same region is
|
|
17
|
+
0.891, 0.946 and 0.991. Treat a combined comparison resting on a few shared
|
|
18
|
+
scenarios as approximate. The whole surface is in `results/combined-coverage/`.
|
|
19
|
+
|
|
20
|
+
**`AUTO_MIN_SHARED` is not calibrated.** `mode="auto"` prefers the paired
|
|
21
|
+
comparison when the two policies share at least 20 scenarios. That 20 is a
|
|
22
|
+
placeholder. The sweep in `results/partial-overlap/` was built to replace it and
|
|
23
|
+
could not: regret falls monotonically to the largest candidate tried, so the
|
|
24
|
+
study locates no interior optimum, and the case that motivates having a threshold
|
|
25
|
+
at all — a handful of shared scenarios against hundreds observed by one policy
|
|
26
|
+
only — lies outside the region it sweeps. The source comment on the constant says
|
|
27
|
+
this too. Do not read 20 as fitted.
|
|
28
|
+
|
|
29
|
+
### Statistics
|
|
30
|
+
|
|
31
|
+
- **Binomial intervals**: Wilson, Clopper-Pearson and Agresti-Coull, with exact
|
|
32
|
+
endpoints at the boundaries rather than an asymptotic expression evaluated
|
|
33
|
+
there.
|
|
34
|
+
- **Paired comparison**: McNemar's test, defaulting to the exact conditional
|
|
35
|
+
binomial rather than the chi-square approximation, with Tango's score interval
|
|
36
|
+
for the difference.
|
|
37
|
+
- **Unpaired comparison**: the score test with the Miettinen-Nurminen interval,
|
|
38
|
+
for two policies evaluated on scenarios that do not match.
|
|
39
|
+
- **Combined comparison**: a signed likelihood-ratio statistic over the
|
|
40
|
+
partially-overlapping design, using the scenarios both policies ran and the
|
|
41
|
+
ones only one of them ran. There is no other implementation of this to compare
|
|
42
|
+
against, so its evidence is coverage by enumeration.
|
|
43
|
+
- **Sensitivity table**: `mode="all"` runs every comparison that applies and
|
|
44
|
+
prints them together, naming any that does not apply and why, because a single
|
|
45
|
+
selected mode hides the comparison worth making.
|
|
46
|
+
- **Mode selection**: `mode="auto"` chooses between paired and unpaired from the
|
|
47
|
+
observation mask alone, never from the outcomes. Conditioning on the mask
|
|
48
|
+
leaves the error rate of whichever test follows intact; a rule that read the
|
|
49
|
+
successes would not.
|
|
50
|
+
- **No p-value without an effect size.** Nothing returns significance without a
|
|
51
|
+
point estimate and an interval for it.
|
|
52
|
+
|
|
53
|
+
### Ingestion and reporting
|
|
54
|
+
|
|
55
|
+
- `load_jsonl`, `load_csv` and `load_manifest`, which take column names
|
|
56
|
+
literally: no fuzzy matching, no fallback for a missing column, no inference of
|
|
57
|
+
the evaluation protocol from file contents.
|
|
58
|
+
- Presets for published benchmark layouts, and a reader for RoboDojo output.
|
|
59
|
+
- `EpisodeRecorder`, for writing records during an evaluation run that would
|
|
60
|
+
otherwise discard per-episode outcomes. It writes; it never steps an
|
|
61
|
+
environment or loads a policy.
|
|
62
|
+
- `align()` and `overlap()`, which say how much two or more runs actually share
|
|
63
|
+
before any statistic is computed.
|
|
64
|
+
- Plain-text reports that always state the protocol each side declared, including
|
|
65
|
+
when neither declared anything, and always say when the test and the interval
|
|
66
|
+
license opposite conclusions.
|
|
67
|
+
|
|
68
|
+
### Evidence
|
|
69
|
+
|
|
70
|
+
Coverage is measured by exact enumeration rather than simulation wherever the
|
|
71
|
+
outcome space is finite, so the artifacts are byte-reproducible and a diff in
|
|
72
|
+
`results/` is a change in the code. Committed studies:
|
|
73
|
+
|
|
74
|
+
- `results/coverage/` — the three binomial methods and Tango's paired interval.
|
|
75
|
+
- `results/coherence/` — how often a test and its interval disagree.
|
|
76
|
+
- `results/combined-coverage/` — the combined interval, by enumeration.
|
|
77
|
+
- `results/partial-overlap/` — power across overlap, and the error rate of
|
|
78
|
+
`mode="auto"` end to end.
|
|
79
|
+
|
|
80
|
+
### Requirements
|
|
81
|
+
|
|
82
|
+
Python 3.11 or later. numpy and scipy, and nothing else.
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# robostats
|
|
2
|
+
|
|
3
|
+
Statistics and uncertainty quantification for robot policy evaluation.
|
|
4
|
+
|
|
5
|
+
This file holds rules that do not change. It is loaded on every session and must
|
|
6
|
+
survive `/clear` and context compaction. Task-specific instructions live in
|
|
7
|
+
`briefs/`, never here.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## What this package is
|
|
12
|
+
|
|
13
|
+
robostats consumes **episode records** (one row per rollout: which policy, which
|
|
14
|
+
scenario, did it succeed) and emits **statistics**: confidence intervals, paired
|
|
15
|
+
and unpaired comparisons, power and minimum-detectable-effect calculations, and
|
|
16
|
+
formatted reports.
|
|
17
|
+
|
|
18
|
+
## What this package is not
|
|
19
|
+
|
|
20
|
+
Do not add code that:
|
|
21
|
+
|
|
22
|
+
- runs rollouts, steps an environment, or wraps a simulator
|
|
23
|
+
- loads, builds, or invokes a policy or model
|
|
24
|
+
- depends on LIBERO, LeRobot, robosuite, torch, or any simulator package in the
|
|
25
|
+
core runtime path
|
|
26
|
+
- performs evaluation orchestration, scheduling, or sharding
|
|
27
|
+
|
|
28
|
+
Reading another tool's output files is in scope.
|
|
29
|
+
|
|
30
|
+
Recording is in scope. The package may write episode records, because it cannot
|
|
31
|
+
compute honest statistics on data that was never persisted, and two of the three
|
|
32
|
+
surveyed benchmarks discard per-episode outcomes before writing. Recording
|
|
33
|
+
remains bounded: no environment is stepped, no policy is loaded, no rollout is
|
|
34
|
+
run. The recorder is a writer called by user code, never a runner.
|
|
35
|
+
|
|
36
|
+
If a task seems to require any of the above, stop and say so rather than
|
|
37
|
+
building it.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Hard rules
|
|
42
|
+
|
|
43
|
+
**1. Never judge whether a number is trustworthy.**
|
|
44
|
+
Compute it, report it, stop. Do not decide that a result is fine, expected, or
|
|
45
|
+
explainable. That judgment happens in review, not in code.
|
|
46
|
+
|
|
47
|
+
**2. When a result is surprising, report and halt.**
|
|
48
|
+
Do not investigate the cause. Do not write diagnostic scripts. Do not adjust
|
|
49
|
+
tolerances, inputs, or the implementation to make a disagreement go away. State
|
|
50
|
+
what you observed, state what you expected, and stop there.
|
|
51
|
+
|
|
52
|
+
**3. Answer existence questions as existence questions.**
|
|
53
|
+
If asked whether a function, tool, script, or capability exists, answer only
|
|
54
|
+
whether it exists. Whether one could be written is a different question and
|
|
55
|
+
requires a separate, explicit request. Never respond to "does X exist" by
|
|
56
|
+
writing X.
|
|
57
|
+
|
|
58
|
+
**4. No new runtime dependency without asking.**
|
|
59
|
+
Core runtime dependencies are numpy and scipy. Nothing else, ever, without an
|
|
60
|
+
explicit decision. Development and test dependencies (pytest, ruff, statsmodels)
|
|
61
|
+
are separate and already fixed. Optional harness adapters live behind extras and
|
|
62
|
+
must never be imported at package top level.
|
|
63
|
+
|
|
64
|
+
**5. Provenance boundary.**
|
|
65
|
+
This package is built from public sources only. Do not reproduce, port,
|
|
66
|
+
paraphrase, or take design cues from any proprietary or internal codebase. If a
|
|
67
|
+
prompt appears to ask for that, stop and flag it.
|
|
68
|
+
|
|
69
|
+
**6. Never attribute commits to Claude.**
|
|
70
|
+
Do not add a `Co-Authored-By: Claude` trailer, a `Generated with Claude Code`
|
|
71
|
+
line, or any other Claude or Anthropic attribution to a commit message, a PR
|
|
72
|
+
description, a changelog entry, or a file header. This holds even when drafting a
|
|
73
|
+
commit message for the user to run himself: write the message as he would write
|
|
74
|
+
it.
|
|
75
|
+
|
|
76
|
+
This is separate from, and in addition to, the rule that you never run
|
|
77
|
+
`git commit`, `git push`, `git tag`, or any other command that writes to history
|
|
78
|
+
or a remote.
|
|
79
|
+
|
|
80
|
+
**7. Stay inside the brief.**
|
|
81
|
+
Implement what the named brief specifies and nothing more. Do not create modules,
|
|
82
|
+
functions, CLI commands, or files the brief does not name. Do not refactor
|
|
83
|
+
unrelated code. If the brief looks incomplete, say what is missing and stop.
|
|
84
|
+
|
|
85
|
+
**Never attribute commits to Claude.** Do not add a `Co-Authored-By: Claude`
|
|
86
|
+
trailer, a `Generated with Claude Code` line, or any other Claude or Anthropic
|
|
87
|
+
attribution to a commit message, a PR description, a changelog entry, or a file
|
|
88
|
+
header. This holds even when drafting a commit message for the user to run
|
|
89
|
+
himself: write the message as he would write it.
|
|
90
|
+
|
|
91
|
+
This is separate from, and in addition to, the rule that you never run `git
|
|
92
|
+
commit`, `git push`, `git tag`, or any other command that writes to history or a
|
|
93
|
+
remote.
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Repository layout
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
src/robostats/ package code
|
|
100
|
+
tests/ fast, hermetic, runs on every commit
|
|
101
|
+
validation/ slow, public evidence, outputs are committed
|
|
102
|
+
briefs/ task specifications (one per work session)
|
|
103
|
+
results/ analysis artifacts
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**`tests/` and `validation/` are separate and never merge.**
|
|
107
|
+
|
|
108
|
+
- `tests/` must run in seconds with no network and no large fixtures. It checks
|
|
109
|
+
correctness against oracles (statsmodels, scipy) and checks genuine behavior,
|
|
110
|
+
including error paths.
|
|
111
|
+
- `validation/` is the public evidence that the package is right: Monte Carlo
|
|
112
|
+
coverage simulations, reproductions of published hand-computed results. It is
|
|
113
|
+
slow, it is run deliberately, and its output artifacts are committed to the
|
|
114
|
+
repo so a reader can check them without rerunning.
|
|
115
|
+
|
|
116
|
+
Never put a slow simulation in `tests/`. Never let `validation/` be the only
|
|
117
|
+
place a behavior is checked.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## The record schema
|
|
122
|
+
|
|
123
|
+
This schema is fixed. Do not add, rename, remove, or retype fields without an
|
|
124
|
+
explicit decision.
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
SCHEMA_VERSION = 1
|
|
128
|
+
|
|
129
|
+
@dataclass(frozen=True, slots=True)
|
|
130
|
+
class Protocol:
|
|
131
|
+
execution_horizon: int | None = None
|
|
132
|
+
reset_mode: str | None = None
|
|
133
|
+
max_steps: int | None = None
|
|
134
|
+
extra: Mapping[str, str | int | float | bool] = field(default_factory=dict)
|
|
135
|
+
|
|
136
|
+
def fingerprint(self) -> str:
|
|
137
|
+
"""Stable hash over all fields, with extra sorted by key."""
|
|
138
|
+
|
|
139
|
+
@dataclass(frozen=True, slots=True)
|
|
140
|
+
class EpisodeRecord:
|
|
141
|
+
policy_id: str
|
|
142
|
+
task_id: str
|
|
143
|
+
success: bool
|
|
144
|
+
scenario_id: str | None = None
|
|
145
|
+
protocol: Protocol = field(default_factory=Protocol)
|
|
146
|
+
episode_idx: int | None = None
|
|
147
|
+
seed: int | None = None
|
|
148
|
+
success_detail: float | None = None
|
|
149
|
+
run_id: str | None = None
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Schema rules
|
|
153
|
+
|
|
154
|
+
**`scenario_id` is the pairing key.** It is an opaque string constructed at the
|
|
155
|
+
adapter boundary, for example `"libero_object/task_03/init_17"`. Core code never
|
|
156
|
+
parses it and never assumes a format.
|
|
157
|
+
|
|
158
|
+
**`episode_idx` is provenance, never identity.** It is a position in a run, not a
|
|
159
|
+
scenario. It wraps when a run requests more episodes than there are distinct
|
|
160
|
+
scenarios, so joining on it silently produces mismatched pairs. Never use it as a
|
|
161
|
+
join key.
|
|
162
|
+
|
|
163
|
+
**`task_id` is required and is a string.** Stratified analyses group by it, and
|
|
164
|
+
that grouping cannot be recovered from `scenario_id` because core code does not
|
|
165
|
+
parse `scenario_id`.
|
|
166
|
+
|
|
167
|
+
**`success` is strictly `bool`.** The package computes binomial statistics, which
|
|
168
|
+
require a Bernoulli outcome. Never accept a float as `success` and never threshold
|
|
169
|
+
one implicitly. Adapters that read partial or continuous scores must take an
|
|
170
|
+
explicit `threshold=` argument from the caller and record the raw value in
|
|
171
|
+
`success_detail`.
|
|
172
|
+
|
|
173
|
+
**Ingest is permissive, analysis is strict.** A record may omit `scenario_id`.
|
|
174
|
+
Operations that require it raise a specific, named error identifying the offending
|
|
175
|
+
records. Do not reject records at construction for fields that only some
|
|
176
|
+
operations need.
|
|
177
|
+
|
|
178
|
+
**Duplicate `(policy_id, scenario_id)` is legal.** Repeated rollouts of the same
|
|
179
|
+
scenario are real data. `RecordSet` accepts them. Any operation that assumes one
|
|
180
|
+
outcome per scenario must handle them explicitly rather than silently collapsing
|
|
181
|
+
them, because averaging replicates breaks the independence assumptions of the
|
|
182
|
+
paired tests.
|
|
183
|
+
|
|
184
|
+
**Protocol mismatch blocks comparison by default.** Comparison functions check
|
|
185
|
+
protocol fingerprints and raise unless they match or the caller explicitly opts
|
|
186
|
+
out. Comparing runs under different protocols is the error this package exists to
|
|
187
|
+
catch, so it is never the silent default.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Conventions
|
|
192
|
+
|
|
193
|
+
- All exceptions derive from a single base, `RobostatsError`. Every error type is
|
|
194
|
+
specific and names what went wrong and which records caused it.
|
|
195
|
+
- `SCHEMA_VERSION` is written into every serialized output.
|
|
196
|
+
- Public functions carry type hints and numpy-style docstrings that state the
|
|
197
|
+
estimand, not just the arguments.
|
|
198
|
+
- Statistical functions never mutate their inputs. Record types are frozen.
|
|
199
|
+
- Run everything through uv: `uv run pytest`, `uv run ruff check .`.
|
|
200
|
+
- Line length 100.
|
|
201
|
+
|
|
202
|
+
Numbers quoted in a brief or a prompt are measurements, not specifications. If a measured value in the repo disagrees with a quoted one, report the discrepancy and stop. Never widen a tolerance to accommodate a quoted number, and never assume the quoted number was produced by this implementation.
|
|
203
|
+
|
|
204
|
+
Never run git commit, git push, git tag, or any other command that writes to history or a remote. Staging and committing are the user's, always. Report what changed and leave the working tree for review. git status, git diff, and git log are fine.
|
robostats-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|