Skip to content

fix: validate retained visual locator regions - #324

Merged
seonghobae merged 16 commits into
codex/preserve-partial-image-regionsfrom
fix/validate-partial-image-regions
Aug 21, 2026
Merged

fix: validate retained visual locator regions#324
seonghobae merged 16 commits into
codex/preserve-partial-image-regionsfrom
fix/validate-partial-image-regions

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Reject locator regions with non-finite, non-positive, negative, or
    out-of-image bounds.
  • Retain valid partial panels and preserve the parent-image evidence behavior
    from fix: retain partial visual regions #320.
  • Keep empty, locator-failure, and single full-image responses parent-only;
    never persist a fabricated full-image region.
  • Add edge tests covering mixed valid, negative, NaN, and missing locator output.

Dependency

Review finding addressed

#320's ADR requires valid bounded regions, but its implementation passed
unbounded locator output to crop/persistence. This follow-up enforces that
boundary before region analysis.

Verification

  • git diff --check and actionlint: passed.
  • uv run --locked --extra dev --extra backend python -m pytest -q:
    742 passed, 16 skipped, 4 warnings.
  • Focused normalization/image tests: 48 passed.
  • Frontend lint, TypeScript build, 136 tests, production build, and Storybook
    build: passed.

No real records, identifiers, or provider credentials are included.

@coderabbitai

coderabbitai Bot commented Aug 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 903d50b7-968c-4d9a-82c9-cbf963b062b5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent review exact current HEAD a4627d6e5e65f3f25bdba9f316cdabb2d933fb0b. Review locator-bound validation and the stacked #320 visual evidence contract; publish a formal review.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Supersede the preceding review request: @opencode-agent review exact current HEAD a4627d6. Review locator-bound validation and the stacked #320 visual evidence contract; publish a formal review.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Supersede all preceding review requests: @opencode-agent review exact current HEAD 3a335ad. Verify the retained visual locator contract, ADR 0104, and the 100% branch-covered fallback tests; publish a formal review.

@devin-ai-integration devin-ai-integration 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.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@seonghobae

Copy link
Copy Markdown
Contributor Author

Supersede the preceding review request: @opencode-agent review exact current HEAD 71f0940. The malformed locator fallback is now covered by the full regression () and normalization branch coverage ().

@seonghobae

Copy link
Copy Markdown
Contributor Author

Supersede the preceding review request: @opencode-agent review exact current HEAD 71f0940. The malformed locator fallback is covered by the full regression: 740 passed, 16 skipped. Normalization branch coverage is 100 percent. Publish a formal review for this SHA.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Supersede prior review targets: current exact HEAD is 71f0940cb3881b2f5452ae79fa45f033dff56a9d. Please review this exact head against codex/preserve-partial-image-regions and publish findings or explicit no-findings.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Supersede all preceding review requests: @opencode-agent review exact current HEAD fdd62a6. The product baseline now records this exact head, 740 Python tests pass with 16 skips, and changed normalization branch coverage is 100 percent. Publish a formal review for this SHA.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Current exact HEAD is fdd62a6f8317c93f9ba5fc27393cfb26c69e584a; the latest commit only refreshes the visual-locator evidence snapshot. Please supersede earlier targets and review this exact head against codex/preserve-partial-image-regions, with findings or explicit no-findings.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Review exact current HEAD fdd62a6. Visual locator validation now rejects malformed/nonfinite/out-of-bounds regions and falls back to bounded source-derived regions; local evidence is 740 Python tests passed, 16 skipped, changed normalizer branch coverage 100 percent, frontend checks and Storybook build passed. Please publish a formal independent review for this exact SHA.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Exact-head review request: current HEAD is fdd62a6f8317c93f9ba5fc27393cfb26c69e584a. Full test suite and frontend lint/test/build are SUCCESS on this HEAD. Please provide an independent approval or concrete findings against this exact commit; merge remains blocked until formal approval and required gate state are satisfied.

…ions' into HEAD

# Conflicts:
#	docs/product-technical-gap-baseline.md
#	lineageweave/post_content_normalization.py
devin-ai-integration[bot]

This comment was marked as resolved.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Fixed the valid review finding on exact current head b1d1b10.

Removed the orphaned duplicate "Integration status: PR #320" note from the PR #324 section of docs/product-technical-gap-baseline.md. The note now appears exactly once under the PR #320 partial visual-region checkpoint.

Validation:

  • exact phrase occurrence assertion: passed (1)
  • git diff --check: passed

Please review this exact current HEAD; predecessor evidence is stale.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Exact current head is 7a49d3e.

Follow-up to the prior review fix:

Validation:

Please review only the exact current head 7a49d3e; earlier evidence is superseded.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Reviewed and repaired against exact current head 2673dac9b507817324217514f4c29d9b843463e0:

  • A malformed VISION locator container (for example, a non-iterable return) previously escaped normalization and incorrectly marked the whole image failed. The locator normalization now fails closed to the existing parent-image fallback, preserving buyer evidence.
  • Added a regression test for the malformed container boundary.
  • Focused verification: uv run --locked --extra dev --extra backend python -m pytest -q tests/test_post_content_normalization.py tests/test_image_content.py tests/test_post_content_persistence_edges.py54 passed.
  • git diff --check passes. Ruff was unavailable in this isolated checkout, so hosted lint remains authoritative.

The PR remains unmergeable until the required independent review and terminal Checks are present; no bypass used.

…ions' into repair/pr324-duplicate-gap-status
…ions' into repair/pr324-duplicate-gap-status

# Conflicts:
#	lineageweave/post_content_normalization.py
#	tests/test_post_content_normalization.py
…ions' into repair/pr324-duplicate-gap-status
@seonghobae
seonghobae enabled auto-merge (squash) August 21, 2026 05:04
@seonghobae seonghobae added the bug Something isn't working label Aug 21, 2026 — with ChatGPT Codex Connector
@seonghobae

Copy link
Copy Markdown
Contributor Author

Current-head review evidence at 53c2b2553d19be6a0573294a2a9a9e693cdc4d2f

The reported duplicate/orphaned PR #320 integration-status note is not present on the current head. Exact search returns one occurrence only:

No code or documentation patch was made because this current-head review finding is already resolved.

@devin-ai-integration devin-ai-integration 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.

Devin Review found 0 new potential issues.

Open in Devin Review

@devin-ai-integration devin-ai-integration 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.

Devin Review found 2 new potential issues.

Open in Devin Review

Comment thread docs/product-technical-gap-baseline.md
Comment on lines +484 to 485
bound to it, so this is not a merge or release claim.
## Image locator and buyer table checkpoint: 2026-08-20

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Missing blank line before heading

The new refresh paragraph runs directly into the ## Image locator and buyer table checkpoint heading with no blank line between them. This breaks the blank-line-before-heading convention used everywhere else in the file and can prevent strict markdown renderers from treating the line as a heading.

Suggested change
bound to it, so this is not a merge or release claim.
## Image locator and buyer table checkpoint: 2026-08-20
bound to it, so this is not a merge or release claim.
## Image locator and buyer table checkpoint: 2026-08-20
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

* fix: keep internal image instructions out of buyer evidence

* fix: protect persisted image region captions

* fix: preserve legitimate Korean image captions

* docs: allocate unique buyer image ADR number

* fix: reject invalid vision region response types

* fix: block internal vision destinations

* fix: keep provider failures out of buyer errors

* feat: trace post processing and Valkey sessions (#345)

* feat: trace post processing and valkey sessions

* docs: align orchestrator runtime pin

* docs: codify telemetry boundary

* fix: normalize OTLP trace endpoint

* chore: pin orchestrator telemetry fix

* fix: keep provider details out of ingestion ledger

* fix: propagate W3C trace context to gateway
@seonghobae
seonghobae merged commit 260e919 into codex/preserve-partial-image-regions Aug 21, 2026
3 of 4 checks passed
seonghobae added a commit that referenced this pull request Aug 21, 2026
* fix: retain partial image regions

* docs: record partial image region gap

* test: cover partial parent vision failure

* fix: safely handle malformed region locator output

* style: use deferred region result annotation

* docs: reconcile partial-region evidence counts

* fix: validate retained visual locator regions (#324)

* fix: reject unbounded visual locator regions

* docs: refresh exact-head product gap audit

* test: cover visual region fallback branches

* fix: fall back from malformed visual locator output

* docs: refresh visual locator exact-head evidence

* test: keep invalid locator fallback coordinate-free

* docs: keep PR 320 status under its checkpoint

* docs: refresh PR 324 exact-head evidence

* fix: safely handle malformed region locator output

* fix: keep internal image instructions out of buyer evidence (#329)

* fix: keep internal image instructions out of buyer evidence

* fix: protect persisted image region captions

* fix: preserve legitimate Korean image captions

* docs: allocate unique buyer image ADR number

* fix: reject invalid vision region response types

* fix: block internal vision destinations

* fix: keep provider failures out of buyer errors

* feat: trace post processing and Valkey sessions (#345)

* feat: trace post processing and valkey sessions

* docs: align orchestrator runtime pin

* docs: codify telemetry boundary

* fix: normalize OTLP trace endpoint

* chore: pin orchestrator telemetry fix

* fix: keep provider details out of ingestion ledger

* fix: propagate W3C trace context to gateway
seonghobae added a commit that referenced this pull request Aug 21, 2026
* fix: separate source whitespace from explicit structure

* docs: record source indentation buyer gap

* fix: expose unexpected content channel defects

* fix: expose recoverable content batch failures

* docs: normalize gap baseline headings

* fix: retain partial visual regions (#320)

* fix: retain partial image regions

* docs: record partial image region gap

* test: cover partial parent vision failure

* fix: safely handle malformed region locator output

* style: use deferred region result annotation

* docs: reconcile partial-region evidence counts

* fix: validate retained visual locator regions (#324)

* fix: reject unbounded visual locator regions

* docs: refresh exact-head product gap audit

* test: cover visual region fallback branches

* fix: fall back from malformed visual locator output

* docs: refresh visual locator exact-head evidence

* test: keep invalid locator fallback coordinate-free

* docs: keep PR 320 status under its checkpoint

* docs: refresh PR 324 exact-head evidence

* fix: safely handle malformed region locator output

* fix: keep internal image instructions out of buyer evidence (#329)

* fix: keep internal image instructions out of buyer evidence

* fix: protect persisted image region captions

* fix: preserve legitimate Korean image captions

* docs: allocate unique buyer image ADR number

* fix: reject invalid vision region response types

* fix: block internal vision destinations

* fix: keep provider failures out of buyer errors

* feat: trace post processing and Valkey sessions (#345)

* feat: trace post processing and valkey sessions

* docs: align orchestrator runtime pin

* docs: codify telemetry boundary

* fix: normalize OTLP trace endpoint

* chore: pin orchestrator telemetry fix

* fix: keep provider details out of ingestion ledger

* fix: propagate W3C trace context to gateway

@devin-ai-integration devin-ai-integration 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.

Devin Review found 4 new potential issues.

Open in Devin Review

Comment thread backend/app/main.py
Comment on lines +2660 to +2664
except Exception as exc: # noqa: BLE001 - provider boundary is fail-closed.
raise HTTPException(
status.HTTP_503_SERVICE_UNAVAILABLE,
"Post chat is unavailable: contextual-orchestrator returned no complete evidence object",
) from exc

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Duplicate unreachable exception handler

Two identical except Exception as exc: blocks now follow the same try (backend/app/main.py:2655-2664). The second can never execute. It is dead copy-paste code, and flake8-bugbear's duplicate-try-block rule can fail on it since only BLE001 is suppressed.

Suggested change
except Exception as exc: # noqa: BLE001 - provider boundary is fail-closed.
raise HTTPException(
status.HTTP_503_SERVICE_UNAVAILABLE,
"Post chat is unavailable: contextual-orchestrator returned no complete evidence object",
) from exc
cited_ids = list(answer.cited_post_ids)
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +35 to +43
with traced(
"lineageweave.valkey.analysis_outbox_xread",
{
"db.system": "redis",
"db.operation.name": "xread",
"lineageweave.stream.kind": "analysis_outbox",
},
):
batches = await client.xread({OUTBOX_STREAM_KEY: last_id}, count=10, block=1000)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔍 Idle blocking reads emit a span every cycle

The worker loops forever calling client.xread(..., block=1000), now wrapped in traced. With an OTLP endpoint configured this produces a new ~1s span roughly once per second per worker even while the stream is idle. No-op when telemetry is off; verify the emitted volume is acceptable when it is on.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +440 to +444
raise TypeError("vision region response was not text JSON")
fenced = re.sub(r"^\s*```(?:json)?\s*|\s*```\s*$", "", content, flags=re.IGNORECASE)
document = json.loads(fenced)
if not isinstance(document, dict):
raise ValueError("vision region response had no regions list")
raise TypeError("vision region response had no regions list")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: locate_regions exception-type change is caller-safe

Switching to TypeError for non-string content and non-dict document does not change behavior: the only production caller, _describe_image_chunk (lineageweave/post_content_normalization.py:187-191), catches Exception and falls back to whole-image evidence. The sibling 'no regions list' path still raises ValueError, so identical-sounding messages now carry different exception types.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +78 to +106
global _CONFIGURED
if _CONFIGURED or os.getenv("OTEL_SDK_DISABLED", "").lower() == "true":
return
_CONFIGURED = True
endpoint = os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT", "").strip()
if trace is None or not endpoint:
return
try:
from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
OTLPSpanExporter,
)
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
except ImportError: # pragma: no cover - guarded by the runtime extra
_LOGGER.warning("OpenTelemetry SDK/exporter is unavailable")
return

resource = Resource.create({
"service.name": os.getenv("OTEL_SERVICE_NAME", service_name),
"service.namespace": "contextualwisdomlab",
})
provider = TracerProvider(resource=resource)
provider.add_span_processor(
BatchSpanProcessor(
OTLPSpanExporter(endpoint=_otlp_trace_endpoint(endpoint))
)
)
trace.set_tracer_provider(provider)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: _CONFIGURED set before setup succeeds

configure_telemetry sets the module global _CONFIGURED = True before verifying the endpoint or importing the SDK/exporter. If the SDK import fails, no provider is installed yet the flag stays set, so any later retry is a no-op. Fine for the single startup call, but blocks reconfiguration if reused.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant