Skip to content

Navigation Menu

Sign in
Sign up

feat(sim,evidence): the 25 → 15 mm world-voxel lever, measured end to end — and it is null - #252

Draft
AdrianLlopart wants to merge 9 commits into
master from
experiment/voxel-resolution-15mm-v2
Draft

feat(sim,evidence): the 25 → 15 mm world-voxel lever, measured end to end — and it is null #252
AdrianLlopart wants to merge 9 commits into
master from
experiment/voxel-resolution-15mm-v2

Conversation

@AdrianLlopart

@AdrianLlopart AdrianLlopart commented Sep 9, 2026
edited
Loading

Copy link
×ばつ the entire quantisation term** — shrinking the cell removes 8.66 mm and leaves ~50 mm beside it. Filed as **#266**, which is the lever this PR's line in `PLAN.md` §5 used to be. 15 mm also makes the concentration *worse* (payload stops 79 % → 97 % of all stops) and costs the grid 0.6 → 2.8 MB republished at 10 Hz — 28 MB/s of DDS against 6. **Phase, reconciled with `PLAN.md` §5.** Two orthogonal axes, both real. On **phase** (was a place declaration live at the stop) it is **33 placing / 20 carrying / 6 pre-grasp** — which is what §5's earlier *11 placing / 7 carrying* census measured, and it was right. On **obstacle identity** it is **9 hit the declared target / 44 hit surrounding scenery**. Crossed over the 53 payload stops: | | hit the declared target | hit scenery | | --- | ---: | ---: | | **placing** (declaration live) | 5 | **28** | | **carrying** (in transit) | 4 | 16 | The **28** is the headline — the payload approaching its declared drop point and clipping the occupancy beside it, exactly the pattern #259 names, now measured at scale rather than at n=11. `utensil` is 20/20 carrying; the other three scenes are placing. **0** stops occur while reaching for an ungrasped object, so picking is untouched. Lever mapping: **#259 reaches the 33 placing stops and nothing else; #266 reaches all 53 regardless of phase.** ## How tested 7 tests on the resolution knob; `tests/unit/test_resolution_ab_pairing.py` drives the real runner through a seam and asserts no two rounds are ever live at once, that the arms alternate, that each keeps its own ROS domain, and that the sidecar boot wait never falls inside an arm pair; `tests/unit/test_resolution_ab_report_pairing.py` covers back-to-back lanes, alternating rounds, and data with no `started_at`. `ruff` and `mypy --strict` clean; method markers checked. ## Standing caveat n = 16 same-party pairs, sd 22.2 mm. This excludes an effect the size of the predicted −8.66 mm; it could **not** resolve a −3 mm one. The claim is "the predicted effect is not there", not "resolution does nothing" — which is why this is parked rather than closed. Closes nothing on its own. Refs #253 (ruling withdrawn — measured), #266 (the lever that replaces it), #259, #264. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01LtssNMqKXzZLfBhW7idZx2 " data-view-component="true"> Copy Markdown
Contributor

Status: draft, parked pending #266. The measurement this PR set out to make is done and it came back null. The tooling is worth keeping and the evidence is worth landing, but the resolution question itself should be re-asked after the payload-geometry investigation (#266), because that is what the null turned out to be about. Not ready to merge as a recommendation either way until then.

What changed

  • OPENRAL_OCTOMAP_RESOLUTION_M on deploy_e2e.launch.py, validated at launch and recorded per round, so a round that changed the resolution can never afterwards be mistaken for one that did not (7 tests).
  • tools/resolution_ab.sh + tools/resolution_ab_report.py — the A/B and its offline report, with INTEGRITY (observed resolution_m per arm) and PAIRING (per-round separation) attestations.
  • tools/voxel_transport_probe.py, tools/stop_ee_speed.py, octree-to-grid C++ tests, harness fixes in validation_matrix.py.
  • The evidence entry for the result, and PLAN.md §5 updated to strike the lever.

Why (the plan) — and what actually happened

The endpoint was deliberately not completion rate: against the predicted 2.7 % → 10.8 % that needs 200 runs/arm for 80 % power (~33 h), and at the 40/arm a battery gives, power is 0.11. So the primary was the paired, continuous quantity the mechanism predicts — per stop, the over-approximation, whose half-diagonal goes 21.65 mm → 12.99 mm, i.e. a −8.66 mm shift.

Three batteries were needed. The first two were voided by instrument defects found along the way, both now fixed and both with their own evidence entries:

  1. every round leaked an octomap_server_node + octomap_voxel_bridge pair whose Fast-DDS lock file starved the next run on that domain to zero action chunks (fixed in fix(cli): reap the world-voxel nodes, and honour the flag that opts parallel workers out #265 , merged);
  2. the runner claimed to interleave the arms and didn't — xargs -P holds a slot for all ROUNDS rounds — and then, once genuinely concurrent, two deploy graphs (~4.9 GB each on a 15.4 GB host with a 9.1 GB baseline) exhausted swap and drove load averages to 225.

The third ran clean: 80 rounds, 79 valid, 0 bond teardowns, both arms verified against their own observed resolution_m, every round paired at a median separation of 0 s.

The result

Comparing only rounds where both arms produced an adjudicable stop on the same party — mixing parties compares different collision events, not resolutions:

same-party paired shift +5.9 mm
95 % CI (bootstrap, 20 000 resamples) [−5.7, +17.7]
predicted −8.66 mmoutside the interval, 2.6 se away
sign test 11 neg / 12 pos, p = 1.000

Wrong sign, not a weak confirmation. Do not quote the report's own PRIMARY line (−1.6 mm): it pools pairs where the 25 mm arm stopped on panda_link7 (excess 77–89 mm) against pairs where the 15 mm arm stopped on the payload.

Why it is null — and what to do instead

The carried payload is lowered to a local AABB; no hull path exists for payloads at all. Over this battery's 424 samples its box reaches a median 50.78 mm (max 88.22 mm) beyond the mesh, against a half-diagonal of 21.65 mm at 25 mm and 12.99 mm at 15 mm. The box is ×ばつ the entire quantisation term — shrinking the cell removes 8.66 mm and leaves ~50 mm beside it. Filed as #266 , which is the lever this PR's line in PLAN.md §5 used to be.

15 mm also makes the concentration worse (payload stops 79 % → 97 % of all stops) and costs the grid 0.6 → 2.8 MB republished at 10 Hz — 28 MB/s of DDS against 6.

Phase, reconciled with PLAN.md §5. Two orthogonal axes, both real. On phase (was a place declaration live at the stop) it is 33 placing / 20 carrying / 6 pre-grasp — which is what §5's earlier 11 placing / 7 carrying census measured, and it was right. On obstacle identity it is 9 hit the declared target / 44 hit surrounding scenery. Crossed over the 53 payload stops:

hit the declared target hit scenery
placing (declaration live) 5 28
carrying (in transit) 4 16

The 28 is the headline — the payload approaching its declared drop point and clipping the occupancy beside it, exactly the pattern #259 names, now measured at scale rather than at n=11. utensil is 20/20 carrying; the other three scenes are placing. 0 stops occur while reaching for an ungrasped object, so picking is untouched. Lever mapping: #259 reaches the 33 placing stops and nothing else; #266 reaches all 53 regardless of phase.

How tested

7 tests on the resolution knob; tests/unit/test_resolution_ab_pairing.py drives the real runner through a seam and asserts no two rounds are ever live at once, that the arms alternate, that each keeps its own ROS domain, and that the sidecar boot wait never falls inside an arm pair; tests/unit/test_resolution_ab_report_pairing.py covers back-to-back lanes, alternating rounds, and data with no started_at. ruff and mypy --strict clean; method markers checked.

Standing caveat

n = 16 same-party pairs, sd 22.2 mm. This excludes an effect the size of the predicted −8.66 mm; it could not resolve a −3 mm one. The claim is "the predicted effect is not there", not "resolution does nothing" — which is why this is parked rather than closed.

Closes nothing on its own. Refs #253 (ruling withdrawn — measured), #266 (the lever that replaces it), #259, #264.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LtssNMqKXzZLfBhW7idZx2

AdrianLlopart force-pushed the experiment/voxel-resolution-15mm-v2 branch from f51977a to 6e60f60 Compare September 9, 2026 17:40
AdrianLlopart added a commit that referenced this pull request Sep 9, 2026
`sudo apt-get update -qq` exits 100 if *any* configured index fails, and the
ubuntu-24.04 runner image ships third-party lists this repo does not use. From
about 17:16 UTC on 2026年09月09日, dl.google.com's chrome index returned a hash-sum
mismatch — Google had republished it and the CDN had not caught up — and every
run since failed at this step, four in a row on #252. None of ffmpeg, libosmesa6
or just come from that repo; all three are in the Ubuntu archive, whose index
downloaded fine each time.
The downstream damage is worse than one red step: the job skips every lane and
`Attest lane coverage` then reports all nineteen as "selected but produced no
ledger record", which reads like a coverage regression rather than an apt
failure.
Tolerate the update and keep `apt-get install` as the gate — a package that
genuinely cannot be fetched still fails on the next line, so nothing real is
suppressed. Scoping the update to the Ubuntu archive instead would assume the
runner keeps its sources in `/etc/apt/sources.list` rather than deb822
`sources.list.d/ubuntu.sources`; that is unverified here, and getting it wrong
leaves no index at all.
`test-ros2.yml` runs its apt inside a ROS container image with no third-party
lists, so it is left alone.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015odfPTtYuixeCXEW4rZ3Gq
Signed-off-by: Adrian <adrianllopart@gmail.com>
AdrianLlopart force-pushed the experiment/voxel-resolution-15mm-v2 branch from 8a1ba80 to fcfb57d Compare September 9, 2026 18:08
AdrianLlopart added a commit that referenced this pull request Sep 10, 2026
`sudo apt-get update -qq` exits 100 if *any* configured index fails, and the
ubuntu-24.04 runner image ships third-party lists this repo does not use. From
about 17:16 UTC on 2026年09月09日, dl.google.com's chrome index returned a hash-sum
mismatch — Google had republished it and the CDN had not caught up — and every
run since failed at this step, four in a row on #252. None of ffmpeg, libosmesa6
or just come from that repo; all three are in the Ubuntu archive, whose index
downloaded fine each time.
The downstream damage is worse than one red step: the job skips every lane and
`Attest lane coverage` then reports all nineteen as "selected but produced no
ledger record", which reads like a coverage regression rather than an apt
failure.
Tolerate the update and keep `apt-get install` as the gate — a package that
genuinely cannot be fetched still fails on the next line, so nothing real is
suppressed. Scoping the update to the Ubuntu archive instead would assume the
runner keeps its sources in `/etc/apt/sources.list` rather than deb822
`sources.list.d/ubuntu.sources`; that is unverified here, and getting it wrong
leaves no index at all.
`test-ros2.yml` runs its apt inside a ROS container image with no third-party
lists, so it is left alone.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015odfPTtYuixeCXEW4rZ3Gq
Signed-off-by: Adrian <adrianllopart@gmail.com>
AdrianLlopart force-pushed the experiment/voxel-resolution-15mm-v2 branch from fcfb57d to 0efeb03 Compare September 10, 2026 06:25
AdrianLlopart added a commit that referenced this pull request Sep 10, 2026
...findings
Rebased onto master past #257/#258, which had rewritten the same §5 the
resolution branch measures. Two conflict hunks resolved by keeping both sides
where they were complementary and the later fact where they were not:
- PLAN §5 lever 3: this branch's cost measurements (kernel 0.825 ms, rasterize
 1.60 ms, wire +55 ms p99, carry speed n=5) stand; master's "octree->grid
 conversion still unmeasured" was wrong the moment this branch landed and is
 replaced. Master's withdrawal of "drop baguette" stands over this branch's
 [x] for it — baguette scored 1/3 with the gate off.
- "Decide #217": this branch's [x] closed-COMPLETED stands; it is a fact.
- 10-tools.md: master's two detector entries plus this branch's
 octomap_resolution_env, markers refreshed post-hook.
Then three things neither side had:
1. The lever-3 reach bound from #258 written into this branch's own item —
 "recovers 8.7 mm in every stop class" is true of the term, not the stops:
 25->15 mm plausibly converts 5 of 20; the 9 with 23-85 mm of excess are
 #254's population and untouched by any resolution.
2. A finding the gate-OFF arm exposed: with the world check OFF, seven runs
 still carry a kernel stop, and every adjudicable one is a hull-fidelity
 false positive on the pair the kernel named — link5<->link7 three times at
 -27..-32 mm reported against +1.4..+4.9 mm certified, link1<->link7 at
 +87.9 mm, payload<->link1 at +25/+69 mm. No voxel in the path. These sit
 inside the 62.5 % ceiling and depress it. link5<->link7 is the pair #191
 retired the ACM exemption for. No issue exists; filing one is the first
 recommendation.
3. "What to test next", ordered by what is unblocked and what each answer
 changes: adjudicate the self-collision false positives; answer #259's
 never-armed allowance question; run the 15 mm A/B with a falsifiable
 prediction of ~5 of 20; widen carry speed to n=13; the top-up.
Refs #252, #253, #254, #256, #258, #259
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LtssNMqKXzZLfBhW7idZx2
Signed-off-by: Adrian <adrianllopart@gmail.com>

Copy link
Copy Markdown
Contributor Author

Rebased onto master (past #257 / #258) — 2026年09月10日

master had rewritten the same PLAN.md §5 this branch measures, so the branch stopped merging cleanly. Rebased; the five original commits are intact, plus one unification commit on top (0efeb03). --force-with-lease pinned to the pre-rebase tip fcfb57d, so nothing anyone else pushed was overwritten.

Conflicts, and how each was resolved

hunk kept dropped, and why
PLAN §5 lever 3 this branch's cost record — kernel 0.825 ms, rasterize 1.60 ms, wire +55 ms p99, carry speed n=5, the _world_voxel_max_cells correction master's "octree→grid conversion still unmeasured" — it was wrong the moment this branch landed
PLAN "drop baguette" master's withdrawal this branch's [x]baguette scored 1/3 with the gate off on the fixed harness, so the 0/11 behind the strike was starved runs
PLAN "Decide #217" this branch's [x] closed COMPLETED master's open item — it is a fact
10-tools.md master's two new detector entries plus this branch's octomap_resolution_env nothing; markers refreshed after the hooks ran

validation_matrix.py and the evidence ledger auto-merged; mypy --strict, ruff, and the 110 tests across both branches' suites pass on the merged result.

What the unification commit adds that neither side had

  1. A reach bound on this branch's own lever-3 item. "Recovers 8.7 mm in every stop class" is true of the term, not the stops. Tracing the 20 adjudicable gate-ON stops to certified truth (fix(plan,evidence): the 18.9 mm over-approximation is bimodal, not "the cell" #258 ): only 8 have an excess a 25 mm cell can account for, 3 of those already sit under 12.99 mm, so 25 → 15 mm plausibly converts 5 of 20. The other 9 (excess 23–85 mm) are Safety-WG ruling needed: ADR-0101 modeled static fixtures — rule on 8.56 mm, not 16.2 mm #254 's population and no resolution reaches them. That's now written next to the "Actionable, with two caveats" paragraph rather than contradicting it from another file.

  2. A finding the gate-OFF arm exposed. With the world check off, seven runs still carry a kernel stop, and every adjudicable one is a hull-fidelity false positive on the exact pair the kernel named: link5↔link7 three times at −27...−32 mm reported vs +1.4...+4.9 mm certified; link1↔link7 at +87.9 mm; payload↔link1 at +25/+69 mm. No voxel in the path. They sit inside the 62.5 % ceiling and depress it, and link5↔link7 is the pair fix(safety): remove the proven-real panda_link5<->panda_link7 ACM exemption #191 retired the exemption for. No issue exists yet.

  3. "What to test next", ordered by what is unblocked and what each answer changes. The 15 mm A/B this PR lists as missing is item 3, with a falsifiable prediction attached (~5 of 20 stops convert; fewer than 3 means the class-B bound is wrong).

The PR description above predates all of this; the numbers in it still hold, they are just no longer the whole picture.

AdrianLlopart added a commit that referenced this pull request Sep 10, 2026
I wrote that "every adjudicable one is a false positive" by comparing the
kernel's reported depth against the certified mesh distance without charging
the pair its budget. That is exactly the error hal_admissible_gap_m's docstring
warns about — "recomputing only the voxel term understates it fourfold ...
turning correct stops into false-positive" — and I made it in a safety-adjacent
entry. Run through the shipped adjudicator, every self stop that scores at all
scores within-quantization.
The three link5<->link7 stops are the kernel finding its hulls genuinely
overlapping and reporting the loose OBB bound, because it runs no
expanding-polytope step; collision.cpp names this exact pair in its own comment
("-31.97 mm for a ~1.5 mm hull interpenetration"). It discloses that with
depth_is_box_bound and the adjudicator charges the 176.4 mm box budget.
What is real, and is now #260: depth_is_box_bound means "a hull refinement was
ATTEMPTED and fell back", and is deliberately clear when none was attempted.
hal_admissible_gap_m read clear as "hull fidelity", charged a hull budget, found
no measured overhang and gave up — so every self-pair naming panda_link1, which
ships no stage-2 hull by decision (Path C withdrew its envelope for moving its
own stops by 0.0003 mm), was permanently unadjudicated. Two of seven here. The
link_link.rule the HAL publishes already says the hull term applies "when BOTH
links ship stage-2 tight geometry"; the implementation never checked it.
Recommendation item 1 is rewritten on the corrected premise.
Refs #252, #260
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LtssNMqKXzZLfBhW7idZx2
Signed-off-by: Adrian <adrianllopart@gmail.com>
AdrianLlopart and others added 9 commits September 10, 2026 20:38
...s this branch touches
Both violations predate this branch and sit on `master`: `lattice_diff` and
`AGridStraddlingTheOctreesKeyRangeStillSeesEveryLeaf` wrap their arguments the
way clang-format does not, and one prose line in the evidence ledger carries a
trailing space. Neither is reachable by CI's quality job, so they surface only
when a commit stages those files — which the next commit does. Split out per
CLAUDE.md §1.15 so the feature diff stays free of drive-by reformatting.
Signed-off-by: Adrian <adrianllopart@gmail.com>
`sudo apt-get update -qq` exits 100 if *any* configured index fails, and the
ubuntu-24.04 runner image ships third-party lists this repo does not use. From
about 17:16 UTC on 2026年09月09日, dl.google.com's chrome index returned a hash-sum
mismatch — Google had republished it and the CDN had not caught up — and every
run since failed at this step, four in a row on #252. None of ffmpeg, libosmesa6
or just come from that repo; all three are in the Ubuntu archive, whose index
downloaded fine each time.
The downstream damage is worse than one red step: the job skips every lane and
`Attest lane coverage` then reports all nineteen as "selected but produced no
ledger record", which reads like a coverage regression rather than an apt
failure.
Tolerate the update and keep `apt-get install` as the gate — a package that
genuinely cannot be fetched still fails on the next line, so nothing real is
suppressed. Scoping the update to the Ubuntu archive instead would assume the
runner keeps its sources in `/etc/apt/sources.list` rather than deb822
`sources.list.d/ubuntu.sources`; that is unverified here, and getting it wrong
leaves no index at all.
`test-ros2.yml` runs its apt inside a ROS container image with no third-party
lists, so it is left alone.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015odfPTtYuixeCXEW4rZ3Gq
Signed-off-by: Adrian <adrianllopart@gmail.com>
Rebuilt on current `master`. The previous branch was cut before #238 and #239
landed and had drifted into a 45-commit, 25-file duplicate of work that has since
merged through review; every instrument repair, evidence producer and manifest
change it carried is already on `master` in its reviewed form. What was NOT on
master is the resolution-lever measurement, which is what this is.
The lever was struck on an estimate, and the strike was mine and wrong by 32x
(a baseline taken from a hull microbenchmark rather than a round trip, and a
cubic factor applied to a branch-not-taken). All three cost terms are now
measured rather than reasoned about:
 kernel consuming a 15 mm grid p99 0.825 ms (estimated 26.7 ms)
 bridge producing one 1.60 ms against a 100 ms period
 the message on the wire p99 68-83 ms from 19-23 ms at 25 mm
Compute is not the constraint; the map's AGE is. Latency triples, and age is
millimetres too, so it is directly comparable to the 8.66 mm the lever buys.
Settled against measured arm speed rather than an assumption: carry-phase stops
run 0.051 m/s median and 0.265 m/s max, start-state stops exactly 0. Net positive
in three of four corners, and free for the whole start-state class.
Also corrects this branch's own earlier cell count: 15 mm needs 141^3 = 2 803 221
cells, not 376 680, because the coverage ball is sized by the arm's 1016 mm reach.
The cap consequence is real -- a kernel still reserving 614 125 rejects every grid
it is sent, which reads as "no world" and is a fail-OPEN on the world check -- so
`_world_voxel_max_cells` now derives the cap from the resolution.
Ships no default change. The resolution is an opt-in
`OPENRAL_OCTOMAP_RESOLUTION_M` override that `validation_matrix.py` records, so a
round that changed it can never afterwards be mistaken for one that did not.
Shipping 15 mm is a conservatism REDUCTION and needs the safety-WG ruling that
`OpenRAL/management#36` (hazard-log Entry 027) puts on the table.
Tests: 125 unit passed; the 5 launch-file tests pass with the overlay sourced
(they skip without it); 12/12 `openral_octomap_bridge` C++ tests including the new
`RasterizationCostAcrossTreeResolutions` sweep. ruff clean, mypy --strict clean
over tools/ (65 files), refresh_methods_linenos.py --check clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MTE4eEfxW8FvvBnPZL6otg
Signed-off-by: Adrian <adrianllopart@gmail.com>
... had none
The two WG rulings now have trackers (#253 for the 15 mm resolution, #254 for
ADR-0101), so the plan and the issue list agree rather than the plan being the
only record.
Adds two findings that were prose in the evidence ledger and nobody's open item:
- #256 — the ceiling battery's 31.1 % / 2.3 % are lower bounds. It ran both arms
 simultaneously under contention and excluded only sidecar-crash runs, not
 deadline-no-grasp, which turned out to be largely a host-load artifact (spark
 produces zero on these scenes against q-laptop's 40-64 %). The contrast
 survives the paired design; the absolute rates, and therefore the 29-point
 figure the programme is justified by, do not.
- #255 — a full-tier test-ordering flake unrelated to collision work.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MTE4eEfxW8FvvBnPZL6otg
Signed-off-by: Adrian <adrianllopart@gmail.com>
`voxel_transport_probe.per_axis` re-derives the coverage-ball cell count from
its own `RADIUS_M = 1.05` literal rather than from
`deploy_e2e.launch.py::_octomap_coverage_radius`, and
`stop_ee_speed.QUANTISATION_GAIN_M` writes out the difference of two
`validation_matrix.quantization_budget_m` values rather than calling it.
Neither can import its source — the launch file is not a package and both
tools run standalone — so the copies stay, but nothing was holding them to
the originals.
Both failure modes are silent and both land on the numbers this PR argues
from: a probe sized off a stale radius times the wrong grid and still reports
a clean latency, and a drifted 8.66 mm re-argues the whole staleness trade on
a figure nobody would recheck. Two asserts, verified to fail when either
constant is nudged.
Recorded as items 42 and 43 in docs/methods/14-duplication-watch.md.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015odfPTtYuixeCXEW4rZ3Gq
Signed-off-by: Adrian <adrianllopart@gmail.com>
...findings
Rebased onto master past #257/#258, which had rewritten the same §5 the
resolution branch measures. Two conflict hunks resolved by keeping both sides
where they were complementary and the later fact where they were not:
- PLAN §5 lever 3: this branch's cost measurements (kernel 0.825 ms, rasterize
 1.60 ms, wire +55 ms p99, carry speed n=5) stand; master's "octree->grid
 conversion still unmeasured" was wrong the moment this branch landed and is
 replaced. Master's withdrawal of "drop baguette" stands over this branch's
 [x] for it — baguette scored 1/3 with the gate off.
- "Decide #217": this branch's [x] closed-COMPLETED stands; it is a fact.
- 10-tools.md: master's two detector entries plus this branch's
 octomap_resolution_env, markers refreshed post-hook.
Then three things neither side had:
1. The lever-3 reach bound from #258 written into this branch's own item —
 "recovers 8.7 mm in every stop class" is true of the term, not the stops:
 25->15 mm plausibly converts 5 of 20; the 9 with 23-85 mm of excess are
 #254's population and untouched by any resolution.
2. A finding the gate-OFF arm exposed: with the world check OFF, seven runs
 still carry a kernel stop, and every adjudicable one is a hull-fidelity
 false positive on the pair the kernel named — link5<->link7 three times at
 -27..-32 mm reported against +1.4..+4.9 mm certified, link1<->link7 at
 +87.9 mm, payload<->link1 at +25/+69 mm. No voxel in the path. These sit
 inside the 62.5 % ceiling and depress it. link5<->link7 is the pair #191
 retired the ACM exemption for. No issue exists; filing one is the first
 recommendation.
3. "What to test next", ordered by what is unblocked and what each answer
 changes: adjudicate the self-collision false positives; answer #259's
 never-armed allowance question; run the 15 mm A/B with a falsifiable
 prediction of ~5 of 20; widen carry speed to n=13; the top-up.
Refs #252, #253, #254, #256, #258, #259
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LtssNMqKXzZLfBhW7idZx2
Signed-off-by: Adrian <adrianllopart@gmail.com>
I wrote that "every adjudicable one is a false positive" by comparing the
kernel's reported depth against the certified mesh distance without charging
the pair its budget. That is exactly the error hal_admissible_gap_m's docstring
warns about — "recomputing only the voxel term understates it fourfold ...
turning correct stops into false-positive" — and I made it in a safety-adjacent
entry. Run through the shipped adjudicator, every self stop that scores at all
scores within-quantization.
The three link5<->link7 stops are the kernel finding its hulls genuinely
overlapping and reporting the loose OBB bound, because it runs no
expanding-polytope step; collision.cpp names this exact pair in its own comment
("-31.97 mm for a ~1.5 mm hull interpenetration"). It discloses that with
depth_is_box_bound and the adjudicator charges the 176.4 mm box budget.
What is real, and is now #260: depth_is_box_bound means "a hull refinement was
ATTEMPTED and fell back", and is deliberately clear when none was attempted.
hal_admissible_gap_m read clear as "hull fidelity", charged a hull budget, found
no measured overhang and gave up — so every self-pair naming panda_link1, which
ships no stage-2 hull by decision (Path C withdrew its envelope for moving its
own stops by 0.0003 mm), was permanently unadjudicated. Two of seven here. The
link_link.rule the HAL publishes already says the hull term applies "when BOTH
links ship stage-2 tight geometry"; the implementation never checked it.
Recommendation item 1 is rewritten on the corrected premise.
Refs #252, #260
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LtssNMqKXzZLfBhW7idZx2
Signed-off-by: Adrian <adrianllopart@gmail.com>
Answered the open question this plan and #259 both carried. Both the
declaration and the support witness arm at every placing stop.
place_allowance_active is literally `allowance > 0.0` (collision.cpp:1865), and
place_approach_allowance is non-zero only for a cell inside the declared
target's box — so 0 on the 20 latched stops means "this cell is not the declared
target", which is true of every one of them. Where a cell IS the target it
works: the two advisory refusals name b=place:... and the advisory path requires
allowance > 0.0, so it was live and downgraded a latch to an advisory. ADR-0098
argues for exactly this scoping.
The earlier reading — "the allowance never armed at all, which would be a larger
bug" — was a parsing artifact: advisory log lines omit place_allowance_active
and parse_kernel_collision defaults an absent field to False.
Consequence for the recommendation: lever 2 is a conservatism decision in the
same class as #253 and #254, not a bug fix with free upside, and the "up to 9 of
20 stops at zero conservatism" figure is withdrawn.
Refs #259
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LtssNMqKXzZLfBhW7idZx2
Signed-off-by: Adrian <adrianllopart@gmail.com>
...o in the plan
The recommendation still pointed at `ceiling_battery.sh` with a `WORKERS=2`
knob that no longer exists, and said nothing about why the 2026年09月10日 attempt
produced no usable numbers. Two independent instrument defects voided it: the
leaked octomap pair that starved the next run on its domain (openral #265),
and a runner that claimed to interleave the arms while `xargs -P` held each
slot for all ROUNDS rounds, so `sink_cup` ran its arms 29 minutes apart.
Records the corrected invocation, both causes, and that none of the 43 rounds
already on disk are poolable with the rerun.
Refs #253
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LtssNMqKXzZLfBhW7idZx2
Signed-off-by: Adrian <adrianllopart@gmail.com>
AdrianLlopart force-pushed the experiment/voxel-resolution-15mm-v2 branch from 97fa9f3 to e7126fc Compare September 10, 2026 18:40
@AdrianLlopart AdrianLlopart changed the title (削除) feat(sim,evidence): measure the 25 → 15 mm world-voxel resolution lever end to end (削除ここまで) (追記) feat(sim,evidence): the 25 → 15 mm world-voxel lever, measured end to end — and it is null (追記ここまで) Sep 11, 2026
AdrianLlopart marked this pull request as draft September 11, 2026 05:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

1 participant

AltStyle によって変換されたページ (->オリジナル) /