Public first-map verification checkpoint — 2026-08-20
Decision: MAINTAINER_DOCKER_SOURCE_PASS / EXTERNAL_COHORT_NOT_READY
Public writes performed by this checkpoint: none
Independent validations accepted: 0 / 3
This checkpoint records a fresh read-only audit of the public develop source,
one maintainer-controlled Docker run, and one source-builder run. It is evidence
that the practical first-map workflow works end to end through both maintained
entry paths; it is not an independent cohort report, a release publication, or
authorization to recruit validators.
Exact public identity
- Repository:
rsasaki0109/lidar_slam_ros2 - Public branch:
develop - Source revision:
dec8ec286953aea42cbcb2f7de70a41042f24e62 - Product version:
0.9.1 - ROS distribution exercised: Jazzy
- Public source route: Getting Started — source quickstart
- Pages manifest: docs-deployment-v1.json
- Deployed page SHA-256:
e675e4a97353b110934ec014e5cfe085a2b364adf5de4447fda994a4bdd2413a
Before the content-contract hardening below, the bounded
check_public_docs_deployment.py audit returned VERIFIED because the old
manifest, route fragment, page size, page hash, product version, and source
revision all matched. The audit now also requires the rendered first-map
handoff markers: fixed-demo output-directory handoff, stable-image/report
compatibility, receipt-only attachment, source receipt-helper fallback, and
stable-image receipt-helper invocation, plus the immutable image identity
check. Against the still-deployed old manifest it correctly returns
NOT_READY with manifest-content-contract-mismatch and
content-marker-missing; the audit detail now enumerates all six absent
markers. This keeps a stale page from reopening the cohort gate merely by
retaining an old revision and matching SHA.
Docker build and first map
The product Dockerfile was built locally from the exact public revision with
LIDARSLAM_SOURCE_DIRTY=false. The resulting image passed these build/runtime
checks:
lidarslam-map --versionreportedlidarslam_ros2 0.9.1;lidarslam-map start --helpexposed the maintained map workflow;- the installed
product-build-info.jsonbounddirty=falseand the exact source revision above; and - the image completed the fixed MID-360 first-map demo from the public Zenodo
dataset (DOI
10.5281/zenodo.14841855, CC-BY 4.0).
The demo verified the archive and extracted bag member hashes before playback. The mapping workflow then completed atomically and produced an Autoware map:
- Autoware verifier: 8 PASS / 0 WARN / 0 FAIL;
- corrected trajectory: 576 poses;
- native RKO-LIO trajectory: 2772 poses;
- generated Lanelet2 structure: 42 lanelets;
- output contract:
map.pcd,pointcloud_map/,lanelet2_map.osm,map_projector_info.yaml, diagnosis, run manifest, and both Markdown/JSON first-map receipts; - first-map receipt status: PASS; all seven receipt checks passed;
- receipt identity: product
0.9.1, commitdec8ec286953aea42cbcb2f7de70a41042f24e62, profilerko_lio_graph_mid360_preset.
This proves the value proposition in a single reproducible path:
public rosbag2 -> sensor/profile preflight -> SLAM -> Autoware-compatible map -> privacy-bounded receipt.
The image and map run were maintainer-controlled local evidence. The image was not pushed to GHCR and no GitHub issue or community message was created.
As a separate read-only compatibility probe, the published
ghcr.io/rsasaki0109/lidar_slam_ros2:v0.9.0-jazzy image was pulled at digest
sha256:6eabb19ac77ad24fd123772333357a0c5bfdb38055945213722f6484e0f134ef and
ran the documented fixed demo against an already retained dataset cache. The
map completed with a PASS receipt (7/7 checks), product 0.9.0, source commit
0df0c4a86df9f68a894c83f8342e4107c3d23b0f, receipt SHA-256
549cc59ca849f757b48d33fb967de3fc8adac7acab401748debccdefcda110d8, and
manifest SHA-256
3237532c01545cdc4a6f32c425c08b06be1819cc3cbfc940f427ff154051fe29.
This was not a clean-host comparable row because the dataset cache was warm.
The same published image exposes no lidarslam-map report command, so its
receipt can be reviewed and attached manually but cannot produce the new
copy-ready handoff until a reviewed image containing the v0.9.1 CLI is
published. This confirms the remaining release/image gate is a real public
compatibility boundary rather than an untested assumption.
The documented read-only
docker image inspect --format='{{index .RepoDigests 0}}' identity check
returned the same immutable digest
ghcr.io/rsasaki0109/lidar_slam_ros2@sha256:6eabb19ac77ad24fd123772333357a0c5bfdb38055945213722f6484e0f134ef.
The published image's installed create_first_map_validation_receipt.py
helper was then exercised against that retained output with the output mounted
read-only and container networking disabled. It printed the same seven-check
PASS summary, including product 0.9.0, commit
0df0c4a86df9f68a894c83f8342e4107c3d23b0f, and manifest SHA-256
3237532c01545cdc4a6f32c425c08b06be1819cc3cbfc940f427ff154051fe29.
This is a compatibility fallback for receipt review; it performs no output
mutation: the pre/post receipt SHA-256 remained
549cc59ca849f757b48d33fb967de3fc8adac7acab401748debccdefcda110d8.
It is now documented for third parties until the reviewed report image is
published.
The same compatibility boundary was checked from the public dec8ec2 source
tree by extracting only its tracked receipt helper and running it with
--json and no --write against the retained source output. It returned
product 0.9.1, the exact public commit, PASS, and all seven checks. This
confirms that the source fallback does not depend on the locally modified
report <output> command; the retained receipt SHA-256 remained
50bd25f7eb1b0199d43ed7819013ffe4748c714ec2f5e936ebd2cb711b5fa636.
Tracking-surface audit
The public tracking issue #422
is open and still reports 0 / 3. Its Docker and own-bag links resolve, but
its source link uses the historical fragment #1-build-the-workspace; the
deployed page currently exposes #1-install-and-build-from-source instead.
The local docs patch keeps the historical fragment as a compatibility anchor
for the next public deployment. Updating the issue body itself remains a
GitHub write and was not performed.
Source route boundary
From a correctly laid out public checkout (<workspace>/src/lidar_slam_ros2),
bash scripts/source_quickstart.sh --dry-run --json returned a ready plan for
the six maintained packages and the fixed first-map demo. A live host attempt
initialized the pinned submodules, then stopped at the documented base-tool
installation stage because this host has no rosdep command and cannot answer
the sudo password prompt. That is a host permission boundary, not a source
build result; no source first-map PASS is claimed from that host attempt.
As a fresh public-state check, a depth-one clone of develop at
dec8ec286953aea42cbcb2f7de70a41042f24e62 was fetched with both pinned
submodules. The public checkout has no package-audit script yet (the expected
pre-publication state), while its own source quickstart dry-run reports
ready, the exact six-package inventory, and all side-effect flags false. The
same unmodified checkout completed source_quickstart.sh --build-only in the
Jazzy builder: rosdep install/check passed and all six packages finished. Its
installed product build-info records source=git, dirty=false, and the exact
dec8ec286953aea42cbcb2f7de70a41042f24e62 revision. Its installed product help
still exposes the older report <session> boundary,
not the candidate report <output> handoff, so the public source fallback
receipt helper remains a required part of the documentation transition. No
first-map demo was run in this clean-state build-only check.
The exact public-clone create_first_map_validation_receipt.py was also run
read-only against the retained stable demo output: it returned the raw
schema-valid receipt PASS with all seven checks true, product 0.9.0, commit
0df0c4a86df9f68a894c83f8342e4107c3d23b0f, and manifest SHA-256
3237532c01545cdc4a6f32c425c08b06be1819cc3cbfc940f427ff154051fe29; the
receipt file remained unchanged.
The offline plan was freshly rerun with an explicit ROS Jazzy workspace and
--viewer none: status=ready, six packages, no missing submodules, and the
only missing host tool was python3-rosdep. Its side-effect contract remained
all false (network_accessed, apt_executed, submodule_checkout,
workspace_build_executed, demo_executed, and filesystem_writes), while
the planned stages retained dependency preparation, a Release source build,
and the fixed demo handoff. This validates the clean-checkout plan without
silently claiming that the dry-run itself built or mapped anything.
To separate that host boundary from the product path, the same public checkout
was also run in the ROS Jazzy builder environment with the exact documented
workspace layout and source_quickstart.sh --build-only. The helper completed
the six-package inventory, rosdep install/rosdep check, Release symlink
build with tests disabled, and the installed CLI smoke. Its build metadata
reported source=git, dirty=false, and the exact public revision above. The
same source-built install then ran the documented fixed MID-360 demo through
source_quickstart.sh --viewer none with the prepared public dataset cache.
The wrapper completed with:
- first-map receipt status: PASS; all seven receipt checks passed;
- receipt identity: product
0.9.1, commitdec8ec286953aea42cbcb2f7de70a41042f24e62, profilerko_lio_graph_mid360_preset; - Autoware verifier: 8 PASS / 0 WARN / 0 FAIL;
- corrected trajectory: 575 poses; native RKO-LIO trajectory: 2772 poses; Lanelet2 structure: 42 lanelets; and
- receipt SHA-256:
12d02409db55d47380d7a9a6c8bfcd25ef323fbf9adb6c69fd920901dbb0f03e.
The source output was also reproduced with the installed product runner after
binding Git's safe-directory metadata; its receipt remained PASS with the
same exact commit and profile (receipt SHA-256
7fc9ce472047be948b3f278cd98996af40bf361ba1d986f96bbd190586db1028). These
container-level runs establish source-path reproducibility, but remain
maintainer-controlled evidence rather than independent cohort validations.
First-map handoff boundary
The fixed Docker/source demo output contains the privacy-bounded receipt,
manifest, diagnosis, and verification log but intentionally has no
session.json page. The previous report command accepted only a session
bundle, so a third party following the demo path could finish mapping but be
blocked at report preparation. The source implementation now accepts either a
verified session bundle or a fixed-demo output directory, revalidates the same
receipt-bound hashes, and emits the schema-valid first-map-handoff-v1 JSON
without writing or contacting GitHub.
Against the retained source-builder output, the direct handoff command returned
READY_FOR_REVIEW with receipt PASS, exact commit
dec8ec286953aea42cbcb2f7de70a41042f24e62, profile
rko_lio_graph_mid360_preset, and manifest SHA-256
69ac21859e623b361822dd08a160c0a5da3248993d8a68eb582ad5c2aa1ada47.
The same installed CLI accepted the maintainer Docker output and returned
READY_FOR_REVIEW with receipt PASS and manifest SHA-256
d7d97c5f8292db95b6fe96a229cedee01eb41ed489c63195d66e0beb7c5d9b8b.
This closes the report-preparation gap for the public fixed-demo route; it
does not create an issue, upload a receipt, or count as an independent report.
The handoff fix and compatibility-anchor edits are currently local changes;
the deployed Pages bytes and existing public Docker images will include them
only after an authorized reviewed publication.
The final runtime stage was then built locally from the current worktree with
the same exact public source revision (local image ID
sha256:0205654aa9c005f90d4df0ec44473487654706f181c979f921272013c479603a).
Its installed CLI exposes report <output> and returned
READY_FOR_REVIEW / PASS for both the current source-builder output and the
retained public v0.9.0-jazzy output. The latter handoff preserved product
0.9.0, commit 0df0c4a86df9f68a894c83f8342e4107c3d23b0f, and manifest SHA
3237532c01545cdc4a6f32c425c08b06be1819cc3cbfc940f427ff154051fe29.
This runtime check is local release-candidate evidence only; it does not
change the public image or release state.
The same Dockerfile was also built locally for ROS 2 Humble as
lidarslam-local-humble-runtime:handoff. The image completed the six-package
build, installed the 138-package runtime closure, and passed the image-stage
lidarslam-map --version/help guard. Its local immutable image identity is
sha256:86ab168ea73c7736a7d75663dc4dfc740ecac0df1a225a019b1a6ea77ffdca5a
and its embedded build-info records revision
b48ef062c09421436bb4a4f721785a9bc216cbf4, dirty: true, and
source: override; this is intentionally a local candidate, not a public
release identity. With the retained public v0.9.0 output mounted read-only,
the Humble image returned READY_FOR_REVIEW, receipt PASS, product 0.9.0,
commit 0df0c4a86df9f68a894c83f8342e4107c3d23b0f, and manifest SHA-256
3237532c01545cdc4a6f32c425c08b06be1819cc3cbfc940f427ff154051fe29.
The receipt SHA-256 stayed
549cc59ca849f757b48d33fb967de3fc8adac7acab401748debccdefcda110d8 before
and after the run. This adds local Humble/Jazzy runtime coverage while
preserving the read-only, no-publication boundary.
To keep this boundary from regressing, both Dockerfile stages and the Docker,
candidate-image, and release smoke checks now fail closed unless the installed
image help contains report <output>. This is a publication guard, not a
claim that the already-published v0.9.0 image has been modified.
The Pages deployment contract now has the same fail-closed property: the
rendered getting-started.html must advertise the fixed-demo output-directory
handoff, the published-v0.9.0/report compatibility boundary, and the
receipt-only attachment rule. The local MkDocs build plus manifest generator
passed these markers; the public site must be redeployed before the audit can
return VERIFIED again.
The repository README now exposes the same receipt-only report next step and
links the independent-validation guide, so a source checkout's front door does
not stop at the older support --first-map spelling.
The installed-product validation script also invokes report --json directly
against the receipt-bearing map directory after its normal session-bundle
check, validates first-map-handoff-v1, and asserts that no output tree is
mutated. The current combined handoff/docs/runtime/installed-CLI group passed
(122 passed), including the stable-image fallback, README entrypoint, and
verification-package assertions. The release checklist now runs the same
package audit before bundle rehearsal, so a release handoff cannot omit this
third-party verification surface.
The rendered local Pages artifact was also audited with the same read-only
deployment verifier used for the public URL. A fresh temporary artifact bound
the current source revision
b48ef062c09421436bb4a4f721785a9bc216cbf4, product 0.9.1, and page
SHA-256 24955689431ea23d2baacecc65082f7cca3320753e4c83794bdff2200f95612a;
all nine deployment checks returned VERIFIED, including all six content
markers. The temporary artifact and manifest were discarded; this proves the
candidate Pages output, not the still-old public deployment.
First-map verification package audit
The checkout now exposes one package-level, read-only audit for the complete third-party handoff surface:
python3 scripts/check_first_map_verification_package.py --json
The local result was READY, with all eight checks true:
- required regular files and schemas;
- Docker/source documentation, including the stable-image helper and digest fallback;
- receipt-only
reportevidence contract; - Dockerfile and image-workflow
report <output>guards; - all six rendered first-map content markers;
- README, English/Japanese Getting Started, and external-validation audit instructions;
- the main, Pages, and release CI gates; and
- release-bundle inclusion of the audit and schema.
The report is schema-valid under
first-map-verification-package-v1.schema.json, declares
network_requested: false and writes_performed: false, and returns
NOT_READY for an incomplete checkout. MkDocs strict plus the deployment
manifest generator passed locally; the generated manifest advertised the same
six marker IDs. The package audit is therefore a local completion gate, not a
claim that the currently deployed Pages bytes or GHCR tags have changed.
An additional release-boundary audit exposed and closed one packaging gap: the
first candidate bundle carried the audit script but not every CLI/source helper
and Docker/docs workflow that the package itself requires. The release
inventory now includes that complete surface, including the source dependency
helper required by the quickstart dry-run. Two byte-identical local builds of
the v0.9.1 candidate bundle produced the same 300-file archive. The
archive digest is intentionally emitted as detached build output rather than
written into this bundled evidence file, which prevents a self-referential
hash claim.
After extraction, running the bundled audit against the extracted root returned
READY with all eight checks true and both network_requested and
writes_performed false. The audit was then invoked from the extracted bundle's
own scripts/check_first_map_verification_package.py, and the bundled
source_quickstart.sh --help exposed the documented workspace, distro,
viewer, build-only, dry-run, and JSON options. This proves the verification
package is self-contained inside the candidate bundle; it remains local
pre-publication evidence.
Remaining public gates
The v0.9.1 release/image identity is still absent from public distribution:
check_published_release.py --version 0.9.1 --json
status: NOT_PUBLISHED
v0.9.1-humble: ABSENT
v0.9.1-jazzy: ABSENT
The latest public GitHub release remains v0.9.0, so a v0.9.0 Docker image and
the v0.9.1 source/docs route cannot form a same-version comparable matrix row.
Human active-time/command-count observations and clean-host source/Docker rows
are also still missing. Because the deployed v0.9.0 image has no report
command and the deployed Getting Started page lacks the receipt-only handoff
markers, copy_ready_handoff_public is now explicitly false in the tracked
cohort contract. The cohort therefore remains WAITING_FOR_PUBLIC_GATES; no
recruitment or external write is authorized.
Next transition
- Publish a reviewed v0.9.1 release and immutable Humble/Jazzy GHCR images (requires explicit maintainer authority).
- Run fresh paired clean-host Docker/source rows at that one identity with human active-time and command-count observations.
- Re-run the public docs provenance and cohort checks, then request the separate community/GitHub write decision.
- Start at most two independent attempts; retain both PASS and FAIL receipts.
Publication handoff (not executed)
The following transition is prepared but intentionally not performed by this checkpoint because it requires separate maintainer authority for a public merge, Pages deployment, release tag, and GHCR publication:
- Review and merge the local docs/CLI/handoff changes into the trusted
developpath; wait for the Pages artifact to finish. - Run the exact public-docs audit for the newly merged
developrevision (the current pre-publication baseline isdec8ec286953aea42cbcb2f7de70a41042f24e62) and product0.9.1:
bash
EXPECTED_PUBLIC_REVISION="$(git rev-parse HEAD)"
python3 scripts/check_public_docs_deployment.py \
--expected-revision "$EXPECTED_PUBLIC_REVISION" \
--expected-product-version 0.9.1 \
--route source-quickstart --json
Continue only when it returns VERIFIED and all six content markers are
present in the deployed page.
3. Publish the reviewed v0.9.1 release and immutable Humble/Jazzy images,
then run:
bash
python3 scripts/check_published_release.py --version 0.9.1 --json
Continue only when the tag, release, and both GHCR image identities are
present and mutually consistent.
4. Run fresh clean-host Docker/source rows at that one identity, record human
active time and command count, and rerun
python3 scripts/first_map_validator_cohort.py --json. Recruitment remains
unauthorized until that report returns a launch-ready state.