physlint 0.3.1__tar.gz → 0.3.2__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.
- physlint-0.3.2/.github/ISSUE_TEMPLATE/evidence-submission.yml +59 -0
- {physlint-0.3.1 → physlint-0.3.2}/CHANGELOG.md +7 -0
- {physlint-0.3.1 → physlint-0.3.2}/PKG-INFO +11 -9
- {physlint-0.3.1 → physlint-0.3.2}/README.md +10 -8
- physlint-0.3.2/docs/assets/launch/exports/evidence-index.png +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/metrics/downloads.json +2 -2
- {physlint-0.3.1 → physlint-0.3.2}/observatory/README.md +2 -2
- {physlint-0.3.1 → physlint-0.3.2}/observatory/app/ObservatoryTable.tsx +7 -6
- {physlint-0.3.1 → physlint-0.3.2}/observatory/app/globals.css +28 -3
- physlint-0.3.2/observatory/app/page.tsx +168 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/data/observations.json +100 -15
- {physlint-0.3.1 → physlint-0.3.2}/observatory/tests/rendered-html.test.mjs +5 -3
- {physlint-0.3.1 → physlint-0.3.2}/pyproject.toml +1 -1
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/_version.py +1 -1
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_cli.py +1 -1
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_report.py +1 -1
- {physlint-0.3.1 → physlint-0.3.2}/uv.lock +1 -1
- {physlint-0.3.1 → physlint-0.3.2}/validation/build_observatory.py +71 -19
- {physlint-0.3.1 → physlint-0.3.2}/validation/manifest.yaml +1 -1
- {physlint-0.3.1 → physlint-0.3.2}/validation/mcap_manifest.yaml +1 -1
- {physlint-0.3.1 → physlint-0.3.2}/validation/survey_manifest.yaml +1 -1
- physlint-0.3.1/observatory/app/ComparisonTable.tsx +0 -56
- physlint-0.3.1/observatory/app/page.tsx +0 -101
- {physlint-0.3.1 → physlint-0.3.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/.github/ISSUE_TEMPLATE/false-positive.yml +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/.github/ISSUE_TEMPLATE/format-request.yml +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/.github/scripts/update_download_metrics.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/.github/workflows/ci.yml +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/.github/workflows/download-metrics.yml +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/.github/workflows/publish-testpypi.yml +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/.github/workflows/publish.yml +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/.github/workflows/real-data-validation.yml +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/.gitignore +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/CONTRIBUTING.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/LICENSE +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/SECURITY.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/adapters/lerobot.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/adapters/mcap-ros2.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/assets/launch/exports/clean-validation.png +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/assets/launch/exports/controlled-nan-failure.png +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/assets/launch/exports/format-compatibility.png +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/assets/launch/exports/validation-summary.png +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/assets/launch/validation-summary.png +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/assets/launch/validation-summary.svg +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/design/mcap-ros.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/launch/README.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/launch/capture-assets.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/launch/post-templates.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/plugins.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/roadmap.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/rules/mcap-ros2-rules.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/rules/mvp-rules.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/validation/compatibility-survey.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/validation/mcap-ros2-2026-08-27.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/docs/validation/real-data-2026-08-23.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/examples/plugins/idle_prefix.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/.gitignore +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/.openai/hosting.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/app/chatgpt-auth.ts +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/app/layout.tsx +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/data/comparisons.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/db/index.ts +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/db/schema.ts +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/drizzle/meta/_journal.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/drizzle.config.ts +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/eslint.config.mjs +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/examples/d1/app/api/notes/route.ts +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/examples/d1/db/schema.ts +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/next-env.d.ts +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/next.config.ts +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/package-lock.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/package.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/postcss.config.mjs +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/public/favicon.png +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/public/favicon.svg +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/public/file.svg +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/public/globe.svg +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/public/physlint-observatory-social.png +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/public/window.svg +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/tsconfig.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/vite.config.ts +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/observatory/worker/index.ts +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/__init__.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/adapters/__init__.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/adapters/base.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/adapters/lerobot.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/adapters/mcap.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/api.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/cli.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/config.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/corruptions.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/engine/__init__.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/engine/baseline.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/engine/cache.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/engine/compare.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/engine/discovery.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/engine/planner.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/engine/runner.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/models/__init__.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/models/baseline.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/models/comparison.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/models/dataset.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/models/finding.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/models/mcap.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/models/rule.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/plugins.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/py.typed +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/reporters/__init__.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/reporters/atomic.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/reporters/html.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/reporters/json.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/reporters/junit.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/reporters/sarif.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/reporters/terminal.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/rules/__init__.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/rules/common.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/rules/duplication.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/rules/manifest.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/rules/mcap.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/rules/numeric.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/rules/temporal.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/src/physlint/rules/video.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/conftest.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_adapter.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_baseline.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_cache.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_compare.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_config.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_corruptions.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_mcap_adapter.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_mcap_rules.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_mcap_validation_harness.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_observatory_data.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_plugins.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_prepare_demo.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_release_metadata.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_reporters.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_rules.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_survey_harness.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/tests/test_validation_harness.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/README.md +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/__init__.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/harness.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/mcap_harness.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/prepare_demo.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/render_assets.py +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/lerobot-survey-2026-08-30/check-aloha-battery.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/lerobot-survey-2026-08-30/check-lekiwi-go2.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/lerobot-survey-2026-08-30/check-libero-spatial.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/lerobot-survey-2026-08-30/check-pusht.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/lerobot-survey-2026-08-30/check-reachy-head.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/lerobot-survey-2026-08-30/check-so100-pickplace.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/lerobot-survey-2026-08-30/check-so101-teleop.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/lerobot-survey-2026-08-30/check-unitree-h1-greet.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/lerobot-survey-2026-08-30/check-ur10e-robotiq.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/lerobot-survey-2026-08-30/check-xarm-lift.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/lerobot-survey-2026-08-30/summary.csv +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/lerobot-survey-2026-08-30/summary.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/lerobot-survey-2026-08-30/summary.sha256 +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/mcap-ros2-2026-08-26/foxglove-ten-messages.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/mcap-ros2-2026-08-26/robotis-arx5-button.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/mcap-ros2-2026-08-26/ros2-joint-state-clean.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/mcap-ros2-2026-08-26/ros2-joint-state-corrupt.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/mcap-ros2-2026-08-26/summary.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/real-data-2026-08-24/clean-panda.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/real-data-2026-08-24/clean-rover.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/real-data-2026-08-24/clean-sentinel.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/real-data-2026-08-24/clean-so101.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/real-data-2026-08-24/corruption-nan.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/real-data-2026-08-24/corruption-reordered.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/real-data-2026-08-24/corruption-truncated.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/real-data-2026-08-24/summary.csv +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/reports/real-data-2026-08-24/summary.json +0 -0
- {physlint-0.3.1 → physlint-0.3.2}/validation/survey_harness.py +0 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: Community evidence submission
|
|
2
|
+
description: Put a public robot dataset or recording on the Physlint Community Evidence Atlas.
|
|
3
|
+
title: "[evidence]: "
|
|
4
|
+
labels: ["evidence", "community"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for contributing to the public map of robot data health. Submit only public, non-sensitive sources that can be revision-pinned. Do not attach private datasets, credentials, or reports containing private paths.
|
|
10
|
+
- type: input
|
|
11
|
+
id: source
|
|
12
|
+
attributes:
|
|
13
|
+
label: Public dataset or recording
|
|
14
|
+
description: Link the public repository, dataset, or recording.
|
|
15
|
+
placeholder: https://huggingface.co/datasets/owner/dataset
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: input
|
|
19
|
+
id: revision
|
|
20
|
+
attributes:
|
|
21
|
+
label: Immutable revision
|
|
22
|
+
description: Provide a commit, tag, release, checksum, or other stable revision when available.
|
|
23
|
+
placeholder: Commit SHA, tag, or release identifier
|
|
24
|
+
validations:
|
|
25
|
+
required: true
|
|
26
|
+
- type: dropdown
|
|
27
|
+
id: profile
|
|
28
|
+
attributes:
|
|
29
|
+
label: Data profile
|
|
30
|
+
options:
|
|
31
|
+
- LeRobot
|
|
32
|
+
- Generic MCAP
|
|
33
|
+
- ROS 2 over MCAP
|
|
34
|
+
- Another format
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
- type: textarea
|
|
38
|
+
id: context
|
|
39
|
+
attributes:
|
|
40
|
+
label: Robot and collection context
|
|
41
|
+
description: Tell the community what robot, task, sensors, and collection setup this evidence represents.
|
|
42
|
+
validations:
|
|
43
|
+
required: true
|
|
44
|
+
- type: textarea
|
|
45
|
+
id: expectation
|
|
46
|
+
attributes:
|
|
47
|
+
label: What should we learn from it?
|
|
48
|
+
description: Describe whether you expect a healthy result, a known defect, or a finding that needs review.
|
|
49
|
+
validations:
|
|
50
|
+
required: true
|
|
51
|
+
- type: checkboxes
|
|
52
|
+
id: consent
|
|
53
|
+
attributes:
|
|
54
|
+
label: Publication agreement
|
|
55
|
+
options:
|
|
56
|
+
- label: I confirm this source is public and may be referenced by name in the Community Evidence Atlas.
|
|
57
|
+
required: true
|
|
58
|
+
- label: I understand Physlint will publish scoped validation evidence, not a safety certification or universal quality score.
|
|
59
|
+
required: true
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.2 — 2026-09-06
|
|
4
|
+
|
|
5
|
+
- Launch the Physlint Community Evidence Atlas with 23 published observations, community survey context, real defect stories, and stable evidence links.
|
|
6
|
+
- Add a public evidence-submission workflow for dataset and recording maintainers.
|
|
7
|
+
- Replace the public regressions section with a clearer community narrative while retaining the generated comparison catalog for reproducibility.
|
|
8
|
+
- Refresh the PyPI monthly download snapshot to 289 downloads.
|
|
9
|
+
|
|
3
10
|
## 0.3.1 — 2026-08-30
|
|
4
11
|
|
|
5
12
|
- Add a stratified LeRobot compatibility survey, kept separate from the four-snapshot release gate.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: physlint
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Local-first integrity validation for physical-AI and robot-learning data
|
|
5
5
|
Project-URL: Homepage, https://github.com/pranayjoshi/physlint
|
|
6
6
|
Project-URL: Documentation, https://github.com/pranayjoshi/physlint#readme
|
|
@@ -54,17 +54,19 @@ Local-first, deterministic validation for physical-AI recordings and robot-learn
|
|
|
54
54
|
[](https://pypistats.org/packages/physlint)
|
|
55
55
|

|
|
56
56
|
[](LICENSE)
|
|
57
|
-

|
|
58
58
|
|
|
59
59
|
[Quickstart](#quickstart) · [Demo](#see-it-catch-a-real-defect) · [Rules](#what-physlint-checks) · [Evidence](#reproducible-public-data-evidence) · [Observatory](#physlint-observatory) · [Roadmap](#format-roadmap) · [Contributing](#contributing)
|
|
60
60
|
|
|
61
|
-
<img src="docs/assets/launch/exports/
|
|
61
|
+
<img src="docs/assets/launch/exports/evidence-index.png" alt="Physlint evidence index showing robot dataset and recording health checks across LeRobot, MCAP, and ROS 2 data." width="100%">
|
|
62
62
|
|
|
63
63
|
</div>
|
|
64
64
|
|
|
65
65
|
Physlint finds concrete integrity defects before robot data reaches training. It explains the impact, identifies the affected episode and stream, recommends remediation, writes a stable JSON report, and returns a CI-safe exit code.
|
|
66
66
|
|
|
67
|
-
The released `0.3.
|
|
67
|
+
The released `0.3.2` supports **LeRobot Dataset v3.x**, generic **MCAP** container validation, and a **ROS 2-over-MCAP** semantic profile, plus dataset comparison, reviewed baselines, CI report formats, and a plugin SDK. It also launches the [Community Evidence Atlas](https://physlint.com), where maintainers can explore reproducible findings and submit public robot data for inclusion. Claims stay scoped to pinned conformance data and controlled evidence. Native rosbag2 SQLite remains a conversion workflow.
|
|
68
|
+
|
|
69
|
+
At the `0.3.2` release snapshot, PyPI Stats reported **289 downloads in the preceding month**.
|
|
68
70
|
|
|
69
71
|
> [!IMPORTANT]
|
|
70
72
|
> Physlint validates configured data-integrity contracts. A pass does not certify policy quality, task success, or robot safety.
|
|
@@ -84,13 +86,13 @@ Physlint requires Python 3.11 or newer.
|
|
|
84
86
|
### Install from PyPI
|
|
85
87
|
|
|
86
88
|
```bash
|
|
87
|
-
python -m pip install "physlint[video]==0.3.
|
|
89
|
+
python -m pip install "physlint[video]==0.3.2"
|
|
88
90
|
```
|
|
89
91
|
|
|
90
92
|
To test the exact tagged source instead of the PyPI distribution, install the GitHub release directly:
|
|
91
93
|
|
|
92
94
|
```bash
|
|
93
|
-
python -m pip install "physlint[video] @ git+https://github.com/pranayjoshi/physlint.git@v0.3.
|
|
95
|
+
python -m pip install "physlint[video] @ git+https://github.com/pranayjoshi/physlint.git@v0.3.2"
|
|
94
96
|
```
|
|
95
97
|
|
|
96
98
|
### Check a LeRobot dataset or MCAP recording
|
|
@@ -264,7 +266,7 @@ The CLI has stable exit codes and writes reports atomically, so a basic GitHub A
|
|
|
264
266
|
|
|
265
267
|
```yaml
|
|
266
268
|
- name: Install Physlint
|
|
267
|
-
run: python -m pip install "physlint[video]==0.3.
|
|
269
|
+
run: python -m pip install "physlint[video]==0.3.2"
|
|
268
270
|
|
|
269
271
|
- name: Validate robot dataset
|
|
270
272
|
run: |
|
|
@@ -328,7 +330,7 @@ See the [MCAP/ROS 2 manifest](validation/mcap_manifest.yaml), [reproduction harn
|
|
|
328
330
|
|
|
329
331
|
## Physlint Observatory
|
|
330
332
|
|
|
331
|
-
The repository now includes the [Physlint
|
|
333
|
+
The repository now includes the [Physlint Community Evidence Atlas](observatory/): a profile-aware public map spanning LeRobot, MCAP, and ROS 2, with real defect stories and a contribution path for dataset maintainers. It deliberately does not collapse unlike contracts into one universal quality score. Every row exposes provenance, applicable checks, findings, a stable share link, and a sanitized report.
|
|
332
334
|
|
|
333
335
|
## Format roadmap
|
|
334
336
|
|
|
@@ -442,7 +444,7 @@ Read [CONTRIBUTING.md](CONTRIBUTING.md), open a format request, or join [GitHub
|
|
|
442
444
|
|
|
443
445
|
## Project status
|
|
444
446
|
|
|
445
|
-
Physlint is
|
|
447
|
+
Physlint is released. Its claims are deliberately limited to the documented LeRobot, generic MCAP, and ROS 2-over-MCAP boundaries and their committed evidence. The project does not train policies, repair data, host datasets, infer task success, produce an opaque quality score, or certify that a robot or policy is safe.
|
|
446
448
|
|
|
447
449
|
See [CHANGELOG.md](CHANGELOG.md) for release notes.
|
|
448
450
|
|
|
@@ -11,17 +11,19 @@ Local-first, deterministic validation for physical-AI recordings and robot-learn
|
|
|
11
11
|
[](https://pypistats.org/packages/physlint)
|
|
12
12
|

|
|
13
13
|
[](LICENSE)
|
|
14
|
-

|
|
15
15
|
|
|
16
16
|
[Quickstart](#quickstart) · [Demo](#see-it-catch-a-real-defect) · [Rules](#what-physlint-checks) · [Evidence](#reproducible-public-data-evidence) · [Observatory](#physlint-observatory) · [Roadmap](#format-roadmap) · [Contributing](#contributing)
|
|
17
17
|
|
|
18
|
-
<img src="docs/assets/launch/exports/
|
|
18
|
+
<img src="docs/assets/launch/exports/evidence-index.png" alt="Physlint evidence index showing robot dataset and recording health checks across LeRobot, MCAP, and ROS 2 data." width="100%">
|
|
19
19
|
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
22
|
Physlint finds concrete integrity defects before robot data reaches training. It explains the impact, identifies the affected episode and stream, recommends remediation, writes a stable JSON report, and returns a CI-safe exit code.
|
|
23
23
|
|
|
24
|
-
The released `0.3.
|
|
24
|
+
The released `0.3.2` supports **LeRobot Dataset v3.x**, generic **MCAP** container validation, and a **ROS 2-over-MCAP** semantic profile, plus dataset comparison, reviewed baselines, CI report formats, and a plugin SDK. It also launches the [Community Evidence Atlas](https://physlint.com), where maintainers can explore reproducible findings and submit public robot data for inclusion. Claims stay scoped to pinned conformance data and controlled evidence. Native rosbag2 SQLite remains a conversion workflow.
|
|
25
|
+
|
|
26
|
+
At the `0.3.2` release snapshot, PyPI Stats reported **289 downloads in the preceding month**.
|
|
25
27
|
|
|
26
28
|
> [!IMPORTANT]
|
|
27
29
|
> Physlint validates configured data-integrity contracts. A pass does not certify policy quality, task success, or robot safety.
|
|
@@ -41,13 +43,13 @@ Physlint requires Python 3.11 or newer.
|
|
|
41
43
|
### Install from PyPI
|
|
42
44
|
|
|
43
45
|
```bash
|
|
44
|
-
python -m pip install "physlint[video]==0.3.
|
|
46
|
+
python -m pip install "physlint[video]==0.3.2"
|
|
45
47
|
```
|
|
46
48
|
|
|
47
49
|
To test the exact tagged source instead of the PyPI distribution, install the GitHub release directly:
|
|
48
50
|
|
|
49
51
|
```bash
|
|
50
|
-
python -m pip install "physlint[video] @ git+https://github.com/pranayjoshi/physlint.git@v0.3.
|
|
52
|
+
python -m pip install "physlint[video] @ git+https://github.com/pranayjoshi/physlint.git@v0.3.2"
|
|
51
53
|
```
|
|
52
54
|
|
|
53
55
|
### Check a LeRobot dataset or MCAP recording
|
|
@@ -221,7 +223,7 @@ The CLI has stable exit codes and writes reports atomically, so a basic GitHub A
|
|
|
221
223
|
|
|
222
224
|
```yaml
|
|
223
225
|
- name: Install Physlint
|
|
224
|
-
run: python -m pip install "physlint[video]==0.3.
|
|
226
|
+
run: python -m pip install "physlint[video]==0.3.2"
|
|
225
227
|
|
|
226
228
|
- name: Validate robot dataset
|
|
227
229
|
run: |
|
|
@@ -285,7 +287,7 @@ See the [MCAP/ROS 2 manifest](validation/mcap_manifest.yaml), [reproduction harn
|
|
|
285
287
|
|
|
286
288
|
## Physlint Observatory
|
|
287
289
|
|
|
288
|
-
The repository now includes the [Physlint
|
|
290
|
+
The repository now includes the [Physlint Community Evidence Atlas](observatory/): a profile-aware public map spanning LeRobot, MCAP, and ROS 2, with real defect stories and a contribution path for dataset maintainers. It deliberately does not collapse unlike contracts into one universal quality score. Every row exposes provenance, applicable checks, findings, a stable share link, and a sanitized report.
|
|
289
291
|
|
|
290
292
|
## Format roadmap
|
|
291
293
|
|
|
@@ -399,7 +401,7 @@ Read [CONTRIBUTING.md](CONTRIBUTING.md), open a format request, or join [GitHub
|
|
|
399
401
|
|
|
400
402
|
## Project status
|
|
401
403
|
|
|
402
|
-
Physlint is
|
|
404
|
+
Physlint is released. Its claims are deliberately limited to the documented LeRobot, generic MCAP, and ROS 2-over-MCAP boundaries and their committed evidence. The project does not train policies, repair data, host datasets, infer task success, produce an opaque quality score, or certify that a robot or policy is safe.
|
|
403
405
|
|
|
404
406
|
See [CHANGELOG.md](CHANGELOG.md) for release notes.
|
|
405
407
|
|
|
Binary file
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"label": "downloads/month",
|
|
4
|
-
"message": "
|
|
4
|
+
"message": "289",
|
|
5
5
|
"color": "brightgreen",
|
|
6
6
|
"cacheSeconds": 86400,
|
|
7
|
-
"updated_at": "2026-
|
|
7
|
+
"updated_at": "2026-09-07T02:45:03.175664+00:00",
|
|
8
8
|
"source": "https://pypistats.org/api/packages/physlint/recent?period=month"
|
|
9
9
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Physlint
|
|
1
|
+
# Physlint Community Evidence Atlas
|
|
2
2
|
|
|
3
|
-
The public evidence
|
|
3
|
+
The public community evidence atlas for Physlint. It presents revision-pinned LeRobot, MCAP, and ROS 2 validation results, real defect stories, and a path for maintainers to contribute public datasets without collapsing unlike quality contracts into a universal score.
|
|
4
4
|
|
|
5
5
|
Release-gate rows stay Public or Controlled. Compatibility-survey rows are tagged Survey and are not a Hugging Face quality score. See `docs/validation/compatibility-survey.md`.
|
|
6
6
|
|
|
@@ -12,7 +12,8 @@ export type Observation = {
|
|
|
12
12
|
scale: string;
|
|
13
13
|
checks: number;
|
|
14
14
|
findings: number;
|
|
15
|
-
status: "Passed" | "Issues found";
|
|
15
|
+
status: "Passed" | "Issues found" | "Rejected";
|
|
16
|
+
note?: string;
|
|
16
17
|
reportUrl: string;
|
|
17
18
|
sourceUrl?: string;
|
|
18
19
|
revision?: string;
|
|
@@ -49,22 +50,22 @@ export function ObservatoryTable({ observations }: { observations: Observation[]
|
|
|
49
50
|
<table>
|
|
50
51
|
<thead><tr><th>#</th><th>Dataset / recording</th><th>Profile</th><th>Scale</th><th>Checks</th><th>Findings</th><th>Outcome</th><th>Evidence</th></tr></thead>
|
|
51
52
|
<tbody>{filtered.map((item, index) => (
|
|
52
|
-
<tr key={item.id}>
|
|
53
|
+
<tr id={`record-${item.id}`} key={item.id}>
|
|
53
54
|
<td className="rank">{String(index + 1).padStart(2, "0")}</td>
|
|
54
55
|
<td>
|
|
55
56
|
{item.sourceUrl ? <a className="recording-name" href={item.sourceUrl}>{item.name} ↗</a> : <span className="recording-name">{item.name}</span>}
|
|
56
|
-
<span className="recording-meta">{item.robot} · {item.provenance} evidence</span>
|
|
57
|
+
<span className="recording-meta">{item.robot} · {item.provenance} evidence{item.note ? ` · ${item.note}` : ""}</span>
|
|
57
58
|
</td>
|
|
58
59
|
<td><span className={`profile profile-${item.profile.toLowerCase().replace(" ", "-")}`}>{item.profile}</span></td>
|
|
59
60
|
<td>{item.scale}</td><td>{item.checks}</td><td>{item.findings}</td>
|
|
60
|
-
<td><span className={item.status === "Passed" ? "status pass" : "status issue"}>{item.status}</span></td>
|
|
61
|
-
<td><a className="evidence" href={item.reportUrl} aria-label={`Open evidence for ${item.name}`}>Report ↗</a></td>
|
|
61
|
+
<td><span className={item.status === "Passed" ? "status pass" : item.status === "Rejected" ? "status reject" : "status issue"}>{item.status}</span></td>
|
|
62
|
+
<td><a className="evidence" href={item.reportUrl} aria-label={`Open evidence for ${item.name}`}>Report ↗</a><span className="evidence-separator"> · </span><a className="evidence" href={`#record-${item.id}`} aria-label={`Copyable link for ${item.name}`}>Link</a></td>
|
|
62
63
|
</tr>
|
|
63
64
|
))}</tbody>
|
|
64
65
|
</table>
|
|
65
66
|
{filtered.length === 0 && <p className="empty">No observations match this filter.</p>}
|
|
66
67
|
</div>
|
|
67
|
-
<p className="index-note">Order
|
|
68
|
+
<p className="index-note">Order is the catalog, not a ranking. Release-gate rows are the public claim. Survey rows are compatibility observations and may include classified false positives.</p>
|
|
68
69
|
</>
|
|
69
70
|
);
|
|
70
71
|
}
|
|
@@ -62,10 +62,26 @@ tbody tr:hover { background:rgba(255,255,255,.45); }
|
|
|
62
62
|
.profile-mcap { background:#dbe9e5; color:#075f53; }.profile-ros-2 { background:#e6edcb; color:#465a12; }
|
|
63
63
|
.status { display:inline-flex; align-items:center; gap:7px; white-space:nowrap; font-weight:700; }
|
|
64
64
|
.status::before { content:""; width:8px; height:8px; border-radius:50%; background:currentColor; }
|
|
65
|
-
.pass { color:var(--teal); }.issue { color:var(--red); }
|
|
65
|
+
.pass { color:var(--teal); }.issue { color:var(--red); }.reject { color:#8a6a12; }
|
|
66
66
|
.evidence { font:650 11px/1 var(--font-geist-mono); text-underline-offset:4px; }
|
|
67
67
|
.empty { margin:0; padding:40px 10px; color:var(--muted); }
|
|
68
68
|
.index-note { margin:14px 0 0; color:var(--muted); font-size:11px; }
|
|
69
|
+
.evidence-separator { color:var(--line); }
|
|
70
|
+
.findings { padding:70px 0 20px; }
|
|
71
|
+
.finding-grid { display:grid; grid-template-columns:repeat(3,1fr); border-top:2px solid var(--ink); border-left:1px solid var(--line); }
|
|
72
|
+
.finding-grid article { min-height:265px; padding:28px; border-right:1px solid var(--line); border-bottom:1px solid var(--line); background:rgba(255,255,255,.3); }
|
|
73
|
+
.finding-grid strong { display:block; margin-bottom:42px; color:var(--teal); font:650 48px/1 var(--font-geist-mono); letter-spacing:-.06em; }
|
|
74
|
+
.finding-grid h3 { max-width:240px; margin:0 0 12px; font-size:21px; letter-spacing:-.035em; }
|
|
75
|
+
.finding-grid p { margin:0; color:var(--muted); font-size:14px; line-height:1.55; }
|
|
76
|
+
.stories { padding:0 0 110px; }
|
|
77
|
+
.story-grid { display:grid; grid-template-columns:repeat(2,1fr); border-top:2px solid var(--ink); border-left:1px solid var(--line); }
|
|
78
|
+
.story-grid article { display:flex; min-height:340px; padding:28px; flex-direction:column; border-right:1px solid var(--line); border-bottom:1px solid var(--line); background:rgba(255,255,255,.34); }
|
|
79
|
+
.story-meta { display:flex; align-items:center; justify-content:space-between; color:var(--teal); font:700 10px/1 var(--font-geist-mono); letter-spacing:.09em; text-transform:uppercase; }
|
|
80
|
+
.story-grid h3 { max-width:460px; margin:52px 0 14px; font-size:28px; line-height:1.04; letter-spacing:-.045em; }
|
|
81
|
+
.story-grid>article>p { max-width:500px; margin:0; color:var(--muted); font-size:14px; line-height:1.6; }
|
|
82
|
+
.story-footer { display:flex; align-items:end; justify-content:space-between; gap:18px; margin-top:auto; padding-top:30px; }
|
|
83
|
+
.story-footer code { color:var(--teal); font-size:11px; }
|
|
84
|
+
.story-footer a { font:700 11px/1 var(--font-geist-mono); text-underline-offset:4px; }
|
|
69
85
|
.method { padding:110px 0; background:var(--night); color:#f2f2e8; }
|
|
70
86
|
.method>.shell { display:grid; grid-template-columns:.8fr 1.2fr; gap:90px; }
|
|
71
87
|
.light { color:var(--acid); }
|
|
@@ -74,6 +90,15 @@ tbody tr:hover { background:rgba(255,255,255,.45); }
|
|
|
74
90
|
.principles span { color:var(--acid); font:600 11px/1 var(--font-geist-mono); }
|
|
75
91
|
.principles h3 { margin:35px 0 10px; font-size:22px; letter-spacing:-.03em; }
|
|
76
92
|
.principles p { margin:0; color:#b1bdb9; font-size:14px; line-height:1.55; }
|
|
93
|
+
.contribute { display:grid; grid-template-columns:1fr 1fr; gap:80px; padding:110px 0; }
|
|
94
|
+
.contribute h2 { margin:0; font-size:clamp(42px,6vw,72px); line-height:.94; letter-spacing:-.06em; }
|
|
95
|
+
.contribute-copy>p:not(.eyebrow) { max-width:620px; margin:28px 0; color:var(--muted); font-size:17px; line-height:1.6; }
|
|
96
|
+
.contribute-copy .hero-actions { margin:0; }
|
|
97
|
+
.contribute-steps { margin:0; padding:0; list-style:none; border-top:2px solid var(--ink); }
|
|
98
|
+
.contribute-steps li { display:grid; grid-template-columns:55px 1fr; gap:18px; padding:25px 0; border-bottom:1px solid var(--line); }
|
|
99
|
+
.contribute-steps li>span { color:var(--teal); font:700 11px/1.4 var(--font-geist-mono); }
|
|
100
|
+
.contribute-steps h3 { margin:0 0 7px; font-size:18px; letter-spacing:-.025em; }
|
|
101
|
+
.contribute-steps p { margin:0; color:var(--muted); font-size:14px; line-height:1.5; }
|
|
77
102
|
.cta { padding:115px 0; text-align:center; }
|
|
78
103
|
.cta .eyebrow { text-align:center; }
|
|
79
104
|
.cta>div { display:flex; justify-content:center; gap:10px; margin-top:35px; }
|
|
@@ -87,13 +112,13 @@ tbody tr:hover { background:rgba(255,255,255,.45); }
|
|
|
87
112
|
.footer { display:flex; justify-content:space-between; gap:30px; padding:25px 0 35px; border-top:1px solid var(--line); color:var(--muted); font-size:11px; }
|
|
88
113
|
|
|
89
114
|
@media (prefers-reduced-motion:reduce) { * { scroll-behavior:auto!important; transition:none!important; } }
|
|
90
|
-
@media (max-width:900px) { .hero-orbit { opacity:.28; right:-170px; }.method>.shell { grid-template-columns:1fr; gap:55px; } }
|
|
115
|
+
@media (max-width:900px) { .hero-orbit { opacity:.28; right:-170px; }.method>.shell,.contribute { grid-template-columns:1fr; gap:55px; }.finding-grid { grid-template-columns:1fr; }.finding-grid article { min-height:auto; }.finding-grid strong { margin-bottom:24px; } }
|
|
91
116
|
@media (max-width:720px) {
|
|
92
117
|
.shell { width:min(100% - 24px,1180px); }.nav { height:68px; }.nav-links a:not(.github) { display:none; }.hero { padding-top:70px; }
|
|
93
118
|
h1 { font-size:clamp(45px,14vw,70px); }.lede { font-size:17px; }.hero-actions { flex-direction:column; align-items:stretch; }
|
|
94
119
|
.summary { grid-template-columns:1fr 1fr; }.summary div:nth-child(2) { border-right:0; }.summary div:nth-child(-n+2) { border-bottom:1px solid var(--line); }
|
|
95
120
|
.section-heading { display:block; }.section-heading>p { margin-top:14px; }.toolbar { align-items:stretch; flex-direction:column; }.search { width:100%; }
|
|
96
|
-
.method { padding:80px 0; }.principles { grid-template-columns:1fr; }.principles article { min-height:180px; }.cta { padding:85px 0; }.cta>div { flex-direction:column; }
|
|
121
|
+
.method { padding:80px 0; }.principles,.story-grid { grid-template-columns:1fr; }.principles article { min-height:180px; }.story-grid article { min-height:310px; }.contribute { padding:80px 0; }.cta { padding:85px 0; }.cta>div { flex-direction:column; }
|
|
97
122
|
.workflow-grid { grid-template-columns:1fr; }
|
|
98
123
|
.footer { flex-direction:column; }
|
|
99
124
|
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { ObservatoryTable, type Observation } from "./ObservatoryTable";
|
|
3
|
+
import catalog from "../data/observations.json";
|
|
4
|
+
|
|
5
|
+
export const metadata: Metadata = {
|
|
6
|
+
title: "Community Evidence Atlas — robot data health",
|
|
7
|
+
description: "A community map of reproducible health evidence for LeRobot, MCAP, and ROS 2 datasets and recordings.",
|
|
8
|
+
other: { "codex-preview": "development" },
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const repo = "https://github.com/pranayjoshi/physlint";
|
|
12
|
+
const reportRoot = `${repo}/blob/master/validation/reports`;
|
|
13
|
+
const observations: Observation[] = catalog.observations.map((item) => ({
|
|
14
|
+
...item,
|
|
15
|
+
profile: item.profile as Observation["profile"],
|
|
16
|
+
provenance: item.provenance as Observation["provenance"],
|
|
17
|
+
status: item.status as Observation["status"],
|
|
18
|
+
note: typeof item.note === "string" ? item.note : undefined,
|
|
19
|
+
sourceUrl: item.sourceUrl ?? undefined,
|
|
20
|
+
reportUrl: `${reportRoot}/${item.reportPath}`,
|
|
21
|
+
}));
|
|
22
|
+
const ruleRuns = observations.reduce((total, item) => total + item.checks, 0);
|
|
23
|
+
const rosMessages = observations.find((item) => item.id === "robotis-arx5-button")?.scale.split(" ")[0] ?? "7,047";
|
|
24
|
+
const surveyCount = observations.filter((item) => item.provenance === "Survey").length;
|
|
25
|
+
const profileCount = new Set(observations.map((item) => item.profile)).size;
|
|
26
|
+
|
|
27
|
+
const stories = [
|
|
28
|
+
{
|
|
29
|
+
number: "01",
|
|
30
|
+
label: "Confirmed public defect",
|
|
31
|
+
title: "Metadata pointed to shards that were never published.",
|
|
32
|
+
copy: "The Reachy 2 Head sample declared Parquet files that were absent from its public revision. The dataset could be discovered, but not reliably consumed.",
|
|
33
|
+
rule: "manifest.required_files",
|
|
34
|
+
href: `${reportRoot}/lerobot-survey-2026-08-30/check-reachy-head.json`,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
number: "02",
|
|
38
|
+
label: "Controlled evidence",
|
|
39
|
+
title: "One reordered timestamp exposed three timing failures.",
|
|
40
|
+
copy: "A deterministic edit reproduced clock reversal, an unexpected sampling interval, and an excessive gap—without changing the original source.",
|
|
41
|
+
rule: "temporal.monotonic",
|
|
42
|
+
href: `${reportRoot}/real-data-2026-08-24/corruption-reordered.json`,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
number: "03",
|
|
46
|
+
label: "Controlled evidence",
|
|
47
|
+
title: "A single non-finite value was isolated before training.",
|
|
48
|
+
copy: "One injected NaN in robot state was traced to its episode, sample, stream, and dimension with a concrete remediation path.",
|
|
49
|
+
rule: "numeric.finite_values",
|
|
50
|
+
href: `${reportRoot}/real-data-2026-08-24/corruption-nan.json`,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
number: "04",
|
|
54
|
+
label: "ROS 2 evidence",
|
|
55
|
+
title: "A topic gap and malformed JointState were separated cleanly.",
|
|
56
|
+
copy: "The recording showed both a cadence break and a position/name dimension mismatch, each reported under the rule that owns it.",
|
|
57
|
+
rule: "ros2.semantic_consistency",
|
|
58
|
+
href: `${reportRoot}/mcap-ros2-2026-08-26/ros2-joint-state-corrupt.json`,
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
export default function Home() {
|
|
63
|
+
return (
|
|
64
|
+
<main>
|
|
65
|
+
<nav className="nav shell">
|
|
66
|
+
<a className="brand" href="#top" aria-label="Physlint Community Evidence Atlas home"><span className="brand-mark">P/</span><span>Evidence Atlas <small>by Physlint</small></span></a>
|
|
67
|
+
<div className="nav-links"><a href="#index">Atlas</a><a href="#stories">Findings</a><a href="#contribute">Contribute</a><a href="#method">Method</a><a className="github" href={repo}>GitHub ↗</a></div>
|
|
68
|
+
</nav>
|
|
69
|
+
|
|
70
|
+
<section className="hero shell" id="top">
|
|
71
|
+
<div className="hero-copy">
|
|
72
|
+
<p className="eyebrow">Community release · 06 Sep 2026</p>
|
|
73
|
+
<h1>The public map of<br />robot data health.</h1>
|
|
74
|
+
<p className="lede">An open atlas of robotics datasets, recordings, and the integrity evidence behind them. See what was checked, what needs review, and how to add your own data—without a mystery score.</p>
|
|
75
|
+
<div className="hero-actions"><a className="button primary" href="#index">Explore the atlas ↓</a><a className="button secondary" href="#contribute">Put your data on the map ↗</a></div>
|
|
76
|
+
</div>
|
|
77
|
+
<div className="hero-orbit" aria-hidden="true"><span className="orbit orbit-one"/><span className="orbit orbit-two"/><span className="core">P/</span><span className="signal signal-a"/><span className="signal signal-b"/><span className="signal signal-c"/></div>
|
|
78
|
+
<div className="summary" aria-label="Validation summary">
|
|
79
|
+
<div><strong>{observations.length}</strong><span>published observations</span></div>
|
|
80
|
+
<div><strong>{surveyCount}</strong><span>community survey records</span></div>
|
|
81
|
+
<div><strong>{ruleRuns.toLocaleString("en-US")}</strong><span>applicable checks</span></div>
|
|
82
|
+
<div><strong>{profileCount}</strong><span>quality profiles</span></div>
|
|
83
|
+
</div>
|
|
84
|
+
</section>
|
|
85
|
+
|
|
86
|
+
<section className="findings shell" aria-labelledby="findings-title">
|
|
87
|
+
<div className="section-heading">
|
|
88
|
+
<div><p className="eyebrow">What the evidence says today</p><h2 id="findings-title">A snapshot, not a verdict.</h2></div>
|
|
89
|
+
<p>The atlas separates release-gate evidence, community survey observations, and controlled defects so each result stays honest about what it proves.</p>
|
|
90
|
+
</div>
|
|
91
|
+
<div className="finding-grid">
|
|
92
|
+
<article><strong>6</strong><h3>Public sources checked</h3><p>Five healthy datasets or recordings passed their applicable contracts. One MCAP conformance case reproduced its known timestamp defects.</p></article>
|
|
93
|
+
<article><strong>15</strong><h3>Survey snapshots mapped</h3><p>Ten LeRobot v3 datasets were checked in depth. Five older v2 or v2.1 datasets were deliberately rejected rather than guessed through.</p></article>
|
|
94
|
+
<article><strong>{Number(rosMessages).toLocaleString("en-US")}</strong><h3>Real ROS messages decoded</h3><p>A public ARX X5 episode passed its configured ROS 2 contract, showing the atlas extends beyond training-dataset folders.</p></article>
|
|
95
|
+
</div>
|
|
96
|
+
</section>
|
|
97
|
+
|
|
98
|
+
<section className="index shell" id="index" aria-labelledby="index-title">
|
|
99
|
+
<div className="section-heading">
|
|
100
|
+
<div><p className="eyebrow">Community evidence atlas</p><h2 id="index-title">Explore every observation.</h2></div>
|
|
101
|
+
<p>Release-gate rows (Public or Controlled) are the scoped claim. Survey rows are a stratified Hub sample, including classified false positives and fail-closed v2 screens. “Passed” means the applicable checks found no configured blocking issues.</p>
|
|
102
|
+
</div>
|
|
103
|
+
<ObservatoryTable observations={observations} />
|
|
104
|
+
</section>
|
|
105
|
+
|
|
106
|
+
<section className="stories shell" id="stories" aria-labelledby="stories-title">
|
|
107
|
+
<div className="section-heading">
|
|
108
|
+
<div><p className="eyebrow">Evidence, made tangible</p><h2 id="stories-title">What a real defect looks like.</h2></div>
|
|
109
|
+
<p>Each story links to a sanitized report with the exact rule, evidence, impact, and suggested remediation.</p>
|
|
110
|
+
</div>
|
|
111
|
+
<div className="story-grid">
|
|
112
|
+
{stories.map((story) => (
|
|
113
|
+
<article key={story.number}>
|
|
114
|
+
<div className="story-meta"><span>{story.number}</span><span>{story.label}</span></div>
|
|
115
|
+
<h3>{story.title}</h3>
|
|
116
|
+
<p>{story.copy}</p>
|
|
117
|
+
<div className="story-footer"><code>{story.rule}</code><a href={story.href}>Read evidence ↗</a></div>
|
|
118
|
+
</article>
|
|
119
|
+
))}
|
|
120
|
+
</div>
|
|
121
|
+
</section>
|
|
122
|
+
|
|
123
|
+
<section className="workflows shell" id="workflows" aria-labelledby="workflow-title">
|
|
124
|
+
<div className="section-heading">
|
|
125
|
+
<div><p className="eyebrow">Data-engineer workflow</p><h2 id="workflow-title">A quality contract that can live in CI.</h2></div>
|
|
126
|
+
</div>
|
|
127
|
+
<div className="workflow-grid">
|
|
128
|
+
<article><h3>compare</h3><p>Diff two dataset versions or JSON reports. Exit 1 only on new blocking findings.</p><code>physlint compare before/ after/</code></article>
|
|
129
|
+
<article><h3>baseline</h3><p>Accept a known fingerprint with author, reason, and optional expiry. New instances of the same rule still fail.</p><code>physlint baseline . --author ada --reason known</code></article>
|
|
130
|
+
<article><h3>CI reports</h3><p>JSON plus JUnit, SARIF, and a local HTML file. No images or raw samples are embedded.</p><code>--junit-output --sarif-output --html-output</code></article>
|
|
131
|
+
<article><h3>plugins</h3><p>Load a file or entry-point rule. Task-specific idle detection stays out of the default contract.</p><code>plugins: [idle_prefix.py:IdlePrefixRule]</code></article>
|
|
132
|
+
</div>
|
|
133
|
+
</section>
|
|
134
|
+
|
|
135
|
+
<section className="method" id="method">
|
|
136
|
+
<div className="shell">
|
|
137
|
+
<div className="method-title"><p className="eyebrow light">How to read the index</p><h2>Evidence over<br />leaderboard theater.</h2></div>
|
|
138
|
+
<div className="principles">
|
|
139
|
+
<article><span>01</span><h3>Profile-aware</h3><p>LeRobot, generic MCAP, and ROS 2 use separate contracts. Survey rows never collapse into the release-gate claim or a Hub quality score.</p></article>
|
|
140
|
+
<article><span>02</span><h3>Reproducible</h3><p>Sources are revision-pinned. Reports preserve configuration digests, rule versions, and SHA-256 fingerprints.</p></article>
|
|
141
|
+
<article><span>03</span><h3>Privacy-safe</h3><p>Only sanitized evidence is published. Raw robot recordings, images, and full samples stay with their owners.</p></article>
|
|
142
|
+
<article><span>04</span><h3>Open to challenge</h3><p>Every finding identifies its rule and evidence. Disagree? Re-run it, inspect the report, or improve the rule.</p></article>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
</section>
|
|
146
|
+
|
|
147
|
+
<section className="contribute shell" id="contribute" aria-labelledby="contribute-title">
|
|
148
|
+
<div className="contribute-copy">
|
|
149
|
+
<p className="eyebrow">Open call for evidence</p>
|
|
150
|
+
<h2 id="contribute-title">Put your robot data<br />on the map.</h2>
|
|
151
|
+
<p>Share an immutable public dataset or recording and what you expect it to demonstrate. Physlint will keep the source untouched, publish only sanitized evidence, and distinguish confirmed defects from findings that need human review.</p>
|
|
152
|
+
<div className="hero-actions"><a className="button primary" href={`${repo}/issues/new?template=evidence-submission.yml`}>Submit public evidence ↗</a><a className="button secondary" href={`${repo}/discussions`}>Join the discussion ↗</a></div>
|
|
153
|
+
</div>
|
|
154
|
+
<ol className="contribute-steps">
|
|
155
|
+
<li><span>01</span><div><h3>Share a public revision</h3><p>Link a dataset or recording that can be pinned and reproduced.</p></div></li>
|
|
156
|
+
<li><span>02</span><div><h3>Tell us what matters</h3><p>Describe the robot, format, and any real failure mode the community should understand.</p></div></li>
|
|
157
|
+
<li><span>03</span><div><h3>Get transparent evidence</h3><p>A published result names the checks, scope, provenance, and review status—never a universal score.</p></div></li>
|
|
158
|
+
</ol>
|
|
159
|
+
</section>
|
|
160
|
+
|
|
161
|
+
<section className="cta shell">
|
|
162
|
+
<p className="eyebrow">The atlas is open</p><h2>Make robot data quality<br />a shared public practice.</h2>
|
|
163
|
+
<div><code>pip install physlint</code><a className="button primary" href={`${repo}#quickstart`}>Run Physlint ↗</a></div>
|
|
164
|
+
</section>
|
|
165
|
+
<footer className="footer shell"><span>Physlint Community Evidence Atlas · Open source under MIT</span><span>Reports are scoped evidence, not safety certification.</span></footer>
|
|
166
|
+
</main>
|
|
167
|
+
);
|
|
168
|
+
}
|