Skip to content

docs(pipeline): record the yaw-leak localization and R-IEKF validation#427

Merged
Ravenwater merged 3 commits into
mainfrom
docs/record-yaw-leak-riekf-findings
Jun 22, 2026
Merged

docs(pipeline): record the yaw-leak localization and R-IEKF validation#427
Ravenwater merged 3 commits into
mainfrom
docs/record-yaw-leak-riekf-findings

Conversation

@Ravenwater

@Ravenwater Ravenwater commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Records this session's real-data findings on the Engineering Status page — the #212 candidate decomposition now reflects what obs_inspect measured on real EuRoC.

Changes to the candidate table

Test plan

  • Fast CI passes (docs-site build + commitlint)
  • Promote to ready when satisfied

Relates to #212, #337, #347, #348

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Updated the engineering status page with refreshed real-data findings in the “Candidate decomposition” table, including a more detailed breakdown of the yaw null-space leak using per-update EuRoC measurements.
    • Clarified the “FEJ” interpretation and what is now confirmed vs still unmeasured, and tightened several related gating/confidence conclusions (including what was cleared and what remains).
    • Expanded the diagnostic program section with clearer cross-stage guidance on the real-update instrumentation behind the conclusions.
    • Extended the tracking index with a new entry for the right-invariant EKF yaw-leak fix work.

Updates the #212 candidate decomposition with this session's real-data findings
from obs_inspect (#212/#337):

- Yaw null-space leak: confirmed per-update on real V2_03 AND V1_01 (translation
  structurally protected, yaw leaks on 100% of updates, grows with clone drift);
  R-IEKF validated as the fix (yaw leak 0.39 -> 2.3e-16 on the same real
  clone-window perturbations).
- Update algebra: cleared on real data too (consistent leak ~1e-15); notes the
  s6 "non-PSD" was an inspector-predicate artifact, since fixed.
- Measurement noise R: reframed as innovation-level only — accepted-update NIS is
  healthy (0.28); the over-confidence is a state-NEES property pointing back at
  the yaw gauge.
- Isotropic P0 / init scale: ruled out as the e2e lever (init error washes out;
  ATE unchanged when the misfiring dynamic init is suppressed).

Adds the obs_inspect diagnostic to the program section and an R-IEKF (#347/#348)
tracking-index row.

Relates to #212, #337, #347, #348

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: c8136b87-8f04-499b-8c5c-21c660ee7b7f

📥 Commits

Reviewing files that changed from the base of the PR and between 201e7c5 and a191463.

📒 Files selected for processing (1)
  • docs-site/src/content/docs/pipeline/engineering-status.mdx

Walkthrough

Updates engineering-status.mdx with real EuRoC per-update measurements in the candidate decomposition table (yaw null-space leak with clone-window drift, cleared update algebra, rescoped R-understatement, revised P₀ yaw seed), adds an obs_inspect cross-stage diagnostic paragraph linking to Issues #212/#337, and appends a Right-Invariant EKF tracking index row for Issues #347/#348.

Changes

Engineering Status Documentation

Layer / File(s) Summary
Candidate decomposition table rewrites
docs-site/src/content/docs/pipeline/engineering-status.mdx
Yaw null-space leak row expanded with per-update real EuRoC data and clone-window drift linkage; update-algebra row marked cleared; isotropic P₀ row revised to state measured yaw seed magnitude; R understated row rescoped to innovation-level gate-filtered NIS rather than state-level over-confidence.
obs_inspect paragraph and tracking index entry
docs-site/src/content/docs/pipeline/engineering-status.mdx
New paragraph in "The diagnostic program" defines obs_inspect (Issues #212/#337) as the real-update ‖H·N‖ instrument, ties yaw-gauge localization to the candidate table, and reports R-IEKF clone-window validation outcome. Tracking index gains "Right-Invariant EKF (the yaw-leak fix)" row for Issues #347 and #348.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • branes-ai/cortex#426: Implements the obs_inspect real-update R-IEKF yaw-leak measurement that this PR documents in the diagnostic program section and candidate decomposition table.
  • branes-ai/cortex#345: Directly updates the same candidate decomposition and diagnostic program entries around yaw null-space leak and R-IEKF escalation.
  • branes-ai/cortex#338: Implements the observability_probe per-gauge H·N yaw-vs-translation leakage metrics that this PR documents as the obs_inspect mechanism for localizing the #212 yaw NEES leak.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title directly summarizes the main documentation change: recording yaw-leak localization findings and R-IEKF validation results on real data.
Description check ✅ Passed The description covers the core changes with Summary and Changes sections, but omits the required Test Results table and incomplete Checklist; however, the PR explicitly states it's docs-only and test-exempt.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/record-yaw-leak-riekf-findings

Comment @coderabbitai help to get the list of available commands and usage tips.

@Ravenwater Ravenwater self-assigned this Jun 22, 2026
@Ravenwater Ravenwater added this to the Phase 3: VIO milestone Jun 22, 2026
@Ravenwater Ravenwater marked this pull request as ready for review June 22, 2026 01:48

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs-site/src/content/docs/pipeline/engineering-status.mdx`:
- Line 42: The yaw leak measurements (0.39, 619, 2.3e-16) and translation leak
assertions in the engineering-status.mdx document lack unit or dimension
specifications, making it unclear whether they represent dimensionless norms,
radians, degrees, or another quantity. Add clarification either inline or via a
footnote that explains the physical interpretation of these leak
values—specifically, confirm whether they are the norm of the null-space leak
(‖H·N‖) computed as `sqrt(sum ...)` on matrix products, and specify the units
(e.g., dimensionless, radians, degrees). Apply this same clarification to both
line 42 and line 81 to ensure consistent context throughout the document.
- Line 42: The yaw leak value reporting is inconsistent between line 42 and line
81 in the engineering-status.mdx file. Line 42 explicitly states "mean 0.39 /
max 619" with clear qualifiers, but line 81 presents the same finding as "yaw
leak 0.39 → 2.3e-16" without specifying that 0.39 is the mean value, creating
potential confusion about whether it represents the average or peak. Update line
81 to explicitly include the "mean" qualifier by changing "yaw leak 0.39 →
2.3e-16" to "mean yaw leak 0.39 → 2.3e-16" to maintain consistency and precision
with line 42's reporting.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 08d86914-07ed-417a-93cf-852768d2f004

📥 Commits

Reviewing files that changed from the base of the PR and between 9805350 and 25b61d0.

📒 Files selected for processing (1)
  • docs-site/src/content/docs/pipeline/engineering-status.mdx

Comment thread docs-site/src/content/docs/pipeline/engineering-status.mdx Outdated
- State that all leak figures are the dimensionless gauge-leak norm ‖H·N‖.
- Line ~81: "mean yaw leak 0.39 → 2.3e-16" to match the candidate table's mean/max.

Relates to #212

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs-site/src/content/docs/pipeline/engineering-status.mdx`:
- Line 42: The phrase "leak ≡ 0" on line 42 in the translation-leak description
overstates the guarantee as mathematically exact, but the actual test assertions
in observability_inspect.cpp use a tolerance of 1e-9 and the real-data
measurements show values around 1e-15. Change the text "translation is
structurally protected (leak ≡ 0)" to use approximate equality like "leak ≈ 0"
or a tolerance bound "leak < 1e-9" to accurately reflect that the leak is
negligible within measurement precision rather than claiming a hard algebraic
invariant.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: dbeb8d09-6cf4-4c55-8837-00795cd162ac

📥 Commits

Reviewing files that changed from the base of the PR and between 25b61d0 and 201e7c5.

📒 Files selected for processing (1)
  • docs-site/src/content/docs/pipeline/engineering-status.mdx

| Candidate | Stage | Status |
|---|---|---|
| **Yaw null-space leak** (observability) | [S2](/pipeline/stages/s2-imu-propagation/)/[S6](/pipeline/stages/s6-msckf-update/) | **Leading, measured** — the `observability_probe` (#337) localizes the structural NEES over-confidence to the **yaw** gauge: the camera Jacobian annihilates the 4-DoF null space at one consistent linearization (‖H·N‖_yaw = 2e-16) but leaks (0.15 at σ=2 cm) at the evolving estimate. Matches the measured **attitude-NEES ≈ 993** on slow V1_01 (NIS a healthy 1.5) |
| **Yaw null-space leak** (observability) | [S2](/pipeline/stages/s2-imu-propagation/)/[S6](/pipeline/stages/s6-msckf-update/) | **Confirmed on real data; R-IEKF validated as the fix.** The `observability_probe` (#337) localized this synthetically; `obs_inspect` (#212) now measures it **per-update on real EuRoC**, driving the *shipped* Jacobian over the live clone window. (All leak figures here are the **dimensionless gauge-leak norm ‖H·N‖** — the residual measurement information the stacked Jacobian projects onto the unobservable gauge; 0 = perfectly annihilated.) On both **V2_03** and **V1_01** the consistent leak is ~1e-15 (the production Jacobian is correct), **translation is structurally protected** (leak ≡ 0), and the **yaw leak is nonzero on 100% of updates and grows with the clone window's attitude drift** (σθ → 5.6°) — exactly the structural NEES over-confidence (attitude-NEES ≈ 993 on V1_01, NIS a healthy 1.5). At the filter's *own* claimed clone σ the standard yaw leak is mean 0.39 / max 619; the **right-invariant (R-IEKF) parameterization on the same perturbations leaks 2.3e-16** (estimate-independent gauge) — the real-data evidence that R-IEKF is the fix |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify translation leak values from obs_inspect runs on real EuRoC.
# Expected: Either strict zero (≡ 0) or negligible value range (< 1e-10).

# Search for obs_inspect output or test assertions on real data translation leak
rg -i 'translation.*leak' --type=cpp --type=json -C2 tools/src/obs_inspect.cpp tools/

Repository: branes-ai/cortex

Length of output: 1525


🏁 Script executed:

cat -n docs-site/src/content/docs/pipeline/engineering-status.mdx | sed -n '35,50p'

Repository: branes-ai/cortex

Length of output: 5497


🏁 Script executed:

rg -i 'translation leak' --type=cpp -A5 -B5 tools/

Repository: branes-ai/cortex

Length of output: 2094


🏁 Script executed:

fd -i "obs_inspect" -type f | head -20

Repository: branes-ai/cortex

Length of output: 231


🏁 Script executed:

find . -type f \( -name "*.json" -o -name "*.jsonl" -o -name "*obs*" -o -name "*leak*" \) | grep -E "(test|out|result|example)" | head -20

Repository: branes-ai/cortex

Length of output: 136


🏁 Script executed:

rg 'translation.*leak|leak.*translation' --type=hpp --type=cpp -B2 -A2 | head -50

Repository: branes-ai/cortex

Length of output: 88


🏁 Script executed:

rg -i 'obs_inspect.*output\|translation.*value\|leak.*[0-9]' tools/ docs/ --max-count=20

Repository: branes-ai/cortex

Length of output: 42


🏁 Script executed:

wc -l tests/tools/observability_inspect.cpp tests/sdk/observability_probe.cpp

Repository: branes-ai/cortex

Length of output: 153


🏁 Script executed:

cat -n tests/tools/observability_inspect.cpp | head -100

Repository: branes-ai/cortex

Length of output: 5150


Soften the translation-leak phrasing to match measurement tolerance.

Line 42 uses "leak ≡ 0" (mathematically exact), but test assertions (tests/tools/observability_inspect.cpp lines 64, 95–96) pin translation leak to WithinAbs(0.0, 1e-9), and the real-data obs_inspect measurement (documented on line 49 as ~1e-15 on V2_03/V1_01) confirms the leak is negligible, not structurally zero by construction. Change "translation is structurally protected (leak ≡ 0)" to "leak ≈ 0" or "leak < 1e-9" to align with the measured tolerance and avoid overstating an unobservable-by-measurement-precision guarantee as a hard algebraic invariant.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs-site/src/content/docs/pipeline/engineering-status.mdx` at line 42, The
phrase "leak ≡ 0" on line 42 in the translation-leak description overstates the
guarantee as mathematically exact, but the actual test assertions in
observability_inspect.cpp use a tolerance of 1e-9 and the real-data measurements
show values around 1e-15. Change the text "translation is structurally protected
(leak ≡ 0)" to use approximate equality like "leak ≈ 0" or a tolerance bound
"leak < 1e-9" to accurately reflect that the leak is negligible within
measurement precision rather than claiming a hard algebraic invariant.

@Ravenwater

Copy link
Copy Markdown
Contributor Author

Addressed both CodeRabbit nitpicks in 201e7c5:

  1. Units — added that all leak figures are the dimensionless gauge-leak norm ‖H·N‖ (residual measurement information projected onto the unobservable gauge; 0 = annihilated).
  2. "mean" qualifier — the diagnostic-program mention now reads "mean yaw leak 0.39 → 2.3e-16" to match the candidate table's mean/max.

…deRabbit)

CodeRabbit read "leak ≡ 0" as overstated vs the test's 1e-9 tolerance, but that
tolerance / the ~1e-15 figure is the YAW consistent leak. The TRANSLATION leak is
exactly 0 by bit-for-bit ±Hf cancellation (obs_inspect prints 0, not 1e-15).
Spell that out so the exact-zero (translation) vs ~1e-15 (yaw) distinction is
unambiguous.

Relates to #212

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Ravenwater

Copy link
Copy Markdown
Contributor Author

Addressed in a191463: clarified the wording. To be precise — the ≡ 0 referred to the translation leak, which is exactly 0 by bit-for-bit ±Hf cancellation (obs_inspect prints trans 0, not 1e-15). The ~1e-15 you cited is the separate yaw consistent leak. Rather than weaken translation to < 1e-9 (which would understate the exact structural guarantee), I spelled out the exact-0 (translation) vs ~1e-15 (yaw) distinction.

@Ravenwater Ravenwater merged commit e059079 into main Jun 22, 2026
15 checks passed
@Ravenwater Ravenwater deleted the docs/record-yaw-leak-riekf-findings branch June 22, 2026 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant