Skip to content

fix(audit-r3): 8 verified defects from full-package review (D1–D8)#78

Merged
yilibinbin merged 4 commits into
mainfrom
fix/audit-r3-defects
Jul 2, 2026
Merged

fix(audit-r3): 8 verified defects from full-package review (D1–D8)#78
yilibinbin merged 4 commits into
mainfrom
fix/audit-r3-defects

Conversation

@yilibinbin

@yilibinbin yilibinbin commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Audit R3 — verified defect fixes (D1–D8)

Fixes the 8 defects that survived the R3 full-package swarm review
(16 dimensions), internal 2-skeptic verification, and external adversarial
re-review by Codex (gpt-5.5, xhigh) + Gemini (via Antigravity). Full
recommendation doc: docs/CODE_REVIEW_2026_R3.md. TDD throughout (RED verified).

# Fix File
D1 Escape user caption in extrapolation LaTeX table (injection / broken compile — R2's F14 fixed only the error-propagation table) datalab_latex/latex_tables_extrapolation.py:309
D2 Escape user column headers in the same table datalab_latex/latex_tables_extrapolation.py:410
D3 SSE fit result: serialize params/errors via mp.nstr (strings), not float() — preserves precision=80+; OpenAPI schema updated to strings app_web/blueprints/sse.py:461, app_web/openapi.py
D4 Effective sample size: elif not almosteq(W2,0)else (tiny-but-valid positive W2 was silently dropped) datalab_core/statistics_compute.py:380
D5 /api/help_specs no longer echoes str(exc) (path/internal leak) — returns class name, logs server-side app_web/blueprints/api.py:269
D6 Fitting-overview plot render logs the exception before the None fallback app_web/logic/fitting.py:970
D7 Observed-linear fast-path ValueError records its fallback reason instead of pass fitting/runner.py:213
D8 help_specs load logs tried paths before the empty fallback formula_help.py:78

Rejected by external review (not fixed, documented): the security-shim
"dev-mode disables LaTeX sandboxing" finding — production hard-raises on
security-import failure and the dev fallback still forces -no-shell-escape.

Test plan

  • TDD RED verified for D1/D2/D4/D5/D8; D3's regression test caught a
    re-quantize bug in the first fix attempt (mp.mpf(v) at ambient dps).
  • ruff check clean on all changed files.
  • 262 tests pass across latex / statistics / web+SSE+api / fitting / implicit
    + the mypy --strict core-layer gate.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved error handling so failed requests return cleaner, non-sensitive error messages.
    • Preserved high-precision numeric results in streamed fit responses.
    • Fixed weighted statistics to compute results correctly for very small but valid uncertainty values.
    • Improved LaTeX table generation by escaping captions and headers to prevent formatting issues.
    • Added clearer fallback behavior and logging when fitting or help-data loading fails.

Aaronhaohao and others added 4 commits July 2, 2026 07:28
…help_specs error

D1/D2 — latex_tables_extrapolation.py embedded user caption (:309) and column
headers (:410) raw into \caption{} / \multicolumn{}, unescaped — a LaTeX
injection / broken-compile gap (R2's F14 fixed only the error-propagation
table). Escape both via shared.latex_escaping.latex_escape, like the sibling
tables.

D4 — statistics_compute.py:380 guarded effective_n with
`elif not mp.almosteq(W2, 0)`, which is True for tiny-but-valid positive W2
(e.g. very large sigmas), silently dropping effective_n even though W2 is
already known > 0 and finite. Replace the elif with else.

D5 — /api/help_specs (public GET) echoed str(exc) on failure, leaking
filesystem paths/internals. Return only type(exc).__name__ and log full detail
server-side.

TDD throughout (RED verified for each). ruff clean; latex + statistics + api
smoke suites green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
D6 — app_web/logic/fitting.py: the fitting-overview plot render caught all
exceptions and returned None with no log. Keep the graceful fallback but
_logger.exception(...) so the cause reaches server logs.

D7 — fitting/runner.py: the observed-linear fast-path `except ValueError: pass`
discarded the reason for falling back to the general solver. Record it into
observed_linear_skipped (already appended to fallback_history), so the fallback
is traceable.

D8 — formula_help.py: _load_help_specs returned {} on any OSError/JSONDecodeError
with no diagnostic. Log each failed candidate path and a final warning listing
all tried paths before the empty fallback (verified: warning emitted, {} returned).

ruff clean; fitting/implicit/api-smoke suites green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…strings (D3)

The SSE fit result serialized params/param_errors_stat via float(v), rounding
mp.mpf values computed at precision=80+ down to ~17 digits and destroying the
product's high-precision result on the web fit-stream path. Serialize with
mp.nstr(v, precision) instead (mirrors the desktop worker), and update the
OpenAPI FitResult schema (app_web/openapi.py) to declare these as strings, not
numbers (Codex refinement).

Note: the initial attempt wrapped the value in mp.mpf(v) before mp.nstr — that
re-quantizes an existing mpf at the ambient (low) mp.dps back to float
precision. The added >17-significant-digit regression test caught it; the fix
formats the mpf directly.

ruff clean; 93 SSE/web-precision/api tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Records the R3 swarm review (16 dimensions, adversarially verified internally +
externally via Codex/gpt-5.5 and Gemini/Antigravity): 8 confirmed defects
(D1–D8, all fixed in this branch), 1 rejected (security-shim), and 68 soft
recommendations for follow-up (maintainability/perf/testing/type-safety/docs/
bilingual).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR sanitizes exception details returned by the help_specs API, converts SSE/OpenAPI fit parameter serialization from floats to precision-preserving strings, escapes LaTeX caption/header text against injection, removes an incorrect almosteq gate in effective_n computation, adds logging for several previously silent failures, and adds a code review audit document with accompanying tests.

Changes

Security, precision, and error-handling fixes

Layer / File(s) Summary
Sanitize help_specs API error responses
app_web/blueprints/api.py, tests/test_web_api_smoke.py
Errors are logged server-side with full details and only the exception class name is returned to clients; verified with a smoke test.
High-precision fit parameter serialization
app_web/blueprints/sse.py, app_web/openapi.py, tests/test_app_web_precision_concurrency.py
SSE emits params/param_errors_stat as mpmath-formatted decimal strings instead of floats, OpenAPI schema updated to match, and tests verify precision preservation.
Fix effective_n computation for tiny W2
datalab_core/statistics_compute.py, tests/test_statistics_weighted.py
Removes an almosteq(W2, 0) gate so effective_n is computed for any valid positive finite W2, with a regression test for tiny-but-valid W2.
Escape LaTeX captions and headers
datalab_latex/latex_tables_extrapolation.py, tests/test_latex_tables_unit.py
Caption text and header cells are escaped via a LaTeX-escaping helper before embedding in table output, with a unit test checking escaped special characters.
Add logging for previously silent failures
app_web/logic/fitting.py, formula_help.py, fitting/runner.py
Adds module loggers and logs exceptions for plot rendering fallback and help spec loading failures; records fallback reasons when the observed-linear fast path raises ValueError.
Round-3 code review audit document
docs/CODE_REVIEW_2026_R3.md
Adds a documentation file summarizing verified defects, a rejected finding, and improvement recommendations from a review process.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant api_help_specs
  participant Logger
  Client->>api_help_specs: GET /api/help_specs
  api_help_specs->>api_help_specs: exception raised while loading specs
  api_help_specs->>Logger: warning(exc_info=True)
  api_help_specs-->>Client: 500 {error: exception class name only}
Loading
sequenceDiagram
  participant FitEngine
  participant single_fit_events
  participant mpmath
  participant Client
  FitEngine->>single_fit_events: fit_result.params, param_errors_stat
  single_fit_events->>mpmath: nstr(value, precision)
  mpmath-->>single_fit_events: precision-preserving string
  single_fit_events-->>Client: SSE result event with string-serialized params
Loading

Possibly related PRs

  • yilibinbin/DataLab#52: Both PRs modify the self-consistent fitting logic in fitting/runner.py's _fit_self_consistent, one adding ValueError capture for the observed-linear fast path and the other refactoring its routing logic.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the PR’s main scope: fixing eight verified defects from the R3 full-package review.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/audit-r3-defects

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app_web/openapi.py (1)

66-83: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

aic/bic/r2 should be string here too. The fit serializer writes these as decimal strings, so leaving them as number makes the response schema inconsistent.

🤖 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 `@app_web/openapi.py` around lines 66 - 83, The fit response schema is
inconsistent because `aic`, `bic`, and `r2` are declared as JSON numbers even
though the serializer emits them as decimal strings. Update the schema in
`openapi.py` where the fit result properties are defined so `aic`, `bic`, and
`r2` use the same string type as `params` and `param_errors_stat`, keeping the
OpenAPI contract aligned with the serializer.
🧹 Nitpick comments (2)
app_web/blueprints/api.py (1)

267-279: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Consider logger.error/exception instead of warning for a 500 failure.

This branch represents a genuine endpoint failure (HTTP 500), not a recoverable fallback. Per common logging conventions, WARNING is meant for degraded-but-functioning paths while ERROR/CRITICAL signal actual failures that alerting/monitoring typically watches for. Using warning here risks this being filtered out of error-level alerts.

Suggested change
-        current_app.logger.warning("Failed to load help specs", exc_info=True)
+        current_app.logger.error("Failed to load help specs", exc_info=True)
🤖 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 `@app_web/blueprints/api.py` around lines 267 - 279, The exception handler in
api.py for the help-specs load failure is logging a real HTTP 500 as a warning,
which can hide it from error monitoring. Update the logging in the `except
Exception as exc` branch to use `current_app.logger.error` or
`current_app.logger.exception` with `exc_info=True` so the failure is recorded
at error level while keeping the public response unchanged. Keep the full
server-side detail logging in this branch and preserve the redacted
client-facing message returned from the help-specs endpoint.
tests/test_latex_tables_unit.py (1)

136-173: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add a backslash-injection payload to the escaping test.

The new test covers & _ $ # % ~, but not a raw backslash payload (e.g. \input{...} or \write18{...}), which is the more severe injection vector this fix targets. Consider adding an assertion that a literal \ in caption/header text is neutralized (e.g. rendered as \textbackslash{}) rather than surviving as a live LaTeX command prefix.

🤖 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 `@tests/test_latex_tables_unit.py` around lines 136 - 173, The LaTeX escaping
test currently covers special characters but misses the backslash injection
case, which is the key attack vector. Update the test around
generate_latex_table to include a caption or header value containing a literal
backslash sequence like a command prefix, then assert that the rendered output
from generate_latex_table escapes it safely (for example via a neutralized
backslash representation) and that no raw backslash survives in the
caption/header text. Use the existing caption and header checks in
test_generate_latex_table_escapes_caption_and_headers as the place to add this
assertion.
🤖 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.

Outside diff comments:
In `@app_web/openapi.py`:
- Around line 66-83: The fit response schema is inconsistent because `aic`,
`bic`, and `r2` are declared as JSON numbers even though the serializer emits
them as decimal strings. Update the schema in `openapi.py` where the fit result
properties are defined so `aic`, `bic`, and `r2` use the same string type as
`params` and `param_errors_stat`, keeping the OpenAPI contract aligned with the
serializer.

---

Nitpick comments:
In `@app_web/blueprints/api.py`:
- Around line 267-279: The exception handler in api.py for the help-specs load
failure is logging a real HTTP 500 as a warning, which can hide it from error
monitoring. Update the logging in the `except Exception as exc` branch to use
`current_app.logger.error` or `current_app.logger.exception` with
`exc_info=True` so the failure is recorded at error level while keeping the
public response unchanged. Keep the full server-side detail logging in this
branch and preserve the redacted client-facing message returned from the
help-specs endpoint.

In `@tests/test_latex_tables_unit.py`:
- Around line 136-173: The LaTeX escaping test currently covers special
characters but misses the backslash injection case, which is the key attack
vector. Update the test around generate_latex_table to include a caption or
header value containing a literal backslash sequence like a command prefix, then
assert that the rendered output from generate_latex_table escapes it safely (for
example via a neutralized backslash representation) and that no raw backslash
survives in the caption/header text. Use the existing caption and header checks
in test_generate_latex_table_escapes_caption_and_headers as the place to add
this assertion.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5f9050e4-45db-4775-84de-0154ec3af78a

📥 Commits

Reviewing files that changed from the base of the PR and between ed6df05 and a241a98.

📒 Files selected for processing (13)
  • app_web/blueprints/api.py
  • app_web/blueprints/sse.py
  • app_web/logic/fitting.py
  • app_web/openapi.py
  • datalab_core/statistics_compute.py
  • datalab_latex/latex_tables_extrapolation.py
  • docs/CODE_REVIEW_2026_R3.md
  • fitting/runner.py
  • formula_help.py
  • tests/test_app_web_precision_concurrency.py
  • tests/test_latex_tables_unit.py
  • tests/test_statistics_weighted.py
  • tests/test_web_api_smoke.py

@yilibinbin yilibinbin merged commit 44701c6 into main Jul 2, 2026
6 checks passed
@yilibinbin yilibinbin deleted the fix/audit-r3-defects branch July 2, 2026 15:20
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.

2 participants