Core and connector follow-ups from the codebase review (#197) - #206
Merged
icebergai-review-bot[bot] merged 1 commit intoAug 20, 2026
Merged
Conversation
**The shared pytest plugin broke minimal environments.** `iceberg-core` publishes `iceberg_core.testing` under `pytest11`, so pytest imports it in every environment where the package is installed — including one carrying the engine's dependency shape, which is plain `iceberg-core` with no `db` extra and therefore no SQLAlchemy at all (ADR 0002). The import failed at collection, before any test ran, in a package that deliberately does not depend on what it needed. The ORM imports are guarded and the database fixtures skip with a sentence naming what to install; the fixtures stay registered rather than vanishing, so a test that wanted one is reported skipped rather than passing on nothing. **Jira spliced instants from stored state into quoted JQL literals** with only an isinstance check. A discovery window's bounds arrive on the lease, a resume point on the checkpoint, a watermark on the cursor — all three round-trip through the API's database after this connector writes them, and a `"` in one would close the literal and change the query rather than fail it. Each is now checked against the single shape `_minute` writes. An unusable value is dropped rather than fatal: the query widens, so the cost is re-reading issues that dedupe on their fingerprint, which is the trade the resume logic already makes. **Support code copied into each connector is now shared.** `_LazySandbox` was byte-identical in two of them; the extraction-outcome mapping was in all three, and had already drifted — a compression bomb was a `size_limit` on a file share and a `parse_error` in Confluence and Jira, so a manifest reason depended on which connector met the file. Both move to `extraction.py`, beside the outcomes they translate. `REJECTED_BOMB` is a `size_limit` everywhere now, which is the reading the enum's own names point at: `REJECTED_*` is a decision about how big something would become, `FAILED_*` is something that broke. **The enum CHECK-constraint question is decided rather than left open**: no constraint. It would make adding a value a locking migration again — exactly what `native_enum=False` was chosen to avoid — while defending only against a writer holding the database credentials directly, who could drop it as easily as violate it. What makes that safe is that an unknown value can never be *believed*: reading one raises, naming the column's vocabulary. The reasoning is in the docstring and the property it rests on is now a test. Refs ADR 0002. Claude-Session: https://claude.ai/code/session_012sohE85sRDt6t2w3936rGJ Co-authored-by: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Verdict
APPROVE
Completed bounded review across 1 immutable scope(s). No actionable findings in the supplied immutable change.
Scope health
Convergence: healthy. Review mode: initial.
Recommended action: CONTINUE_INCREMENTAL.
- No escalation signals.
Prior findings
| Finding | Status |
|---|---|
| — | No prior finding state |
New findings
No new findings.
Fix-induced regressions
- None evidenced.
Uncertainty
- No material uncertainty recorded.
Validation
- Reviewed the supplied diff; exact-head CI is reported as passed.
Residual risks
- None identified.
icebergai-review-bot
Bot
deleted the
claude/codebase-review-cleanup-ovlli4
branch
August 20, 2026 02:00
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The core and connectors sections of #197, after the API section in #205. The web/deploy section follows; #197 stays open until it lands.
1. The shared pytest plugin broke minimal environments
iceberg-corepublishesiceberg_core.testingunderpytest11, so pytest imports it in every environment where the package is installed — including one carrying the engine's dependency shape: plainiceberg-core, nodbextra, no SQLAlchemy (ADR 0002). The import failed at collection, before a single test ran, in a package that deliberately does not depend on what it needed.The ORM imports are guarded and the database fixtures
pytest.skipwith a sentence naming what to install. They stay registered rather than vanishing — a fixture that disappeared would be an obscurefixture 'session' not found, and a test that wanted a session is now reported skipped rather than passing on nothing.Tested in a subprocess with
sys.modules[name] = None, because the workspace this suite runs in has the extra installed and can never reproduce the condition in-process.2. Jira spliced stored state into quoted JQL literals
Three values reach
f'{field} >= "{start}"'with only anisinstance(str)check: a discovery window's bounds (from the lease), a resume point (from the checkpoint), and a watermark (from the cursor). All three round-trip through the API's database after this connector writes them, and a"in one closes the literal and changes the query rather than failing it.Each is now checked against the single shape
_minutewrites (YYYY-MM-DD HH:MM). An unusable value is dropped, not fatal: the query widens, so the cost is re-reading issues that dedupe on their fingerprint — the same trade the resume logic already states a few lines down ("re-reading costs a duplicate, skipping costs the secret"). A checkpoint carrying one restarts the spec, exactly as an unknown checkpoint version does.3. Support code copied into each connector is now shared
_LazySandboxwas byte-identical in Confluence and Jira. The extraction-outcome mapping was in all three — and had already drifted:REJECTED_BOMBparse_errorsize_limitSame file, same refusal, two manifest reasons depending on which connector met it. Both move to
extraction.py, beside the outcomes they translate and theis_incompleteproperty they must stay in lockstep with.Resolved to
size_limit, which is the reading the enum's own names point at:REJECTED_*is a decision this code made about how big something would become,FAILED_*is something that broke. An operator sent to look for a malformed file by aparse_errorwould find a perfectly well-formed one. No test pinned either behaviour, which is how it drifted — there is one now, plus a check that every non-EXTRACTEDoutcome has an entry so a new member cannot fall into some connector's default.4. The enum CHECK-constraint question, decided
No constraint, and the reasoning is now in the docstring rather than the question being left open:
native_enum=Falsewas chosen to avoid — adding a value becomes DROP/ADD CONSTRAINT, a table scan under an ACCESS EXCLUSIVE lock on Postgres.LookupErrornaming the column's enum and its legal values — verified, not assumed. That property is what the trade rests on, sotest_enum_columns.pypins it; if SQLAlchemy ever starts coercing instead of raising, the decision should be revisited and the test is what will say so.Validation
Every behavioural fix has a test confirmed to fail against the code before it (stashed and re-run). New:
test_pytest_plugin.py,test_enum_columns.py,test_extraction_reasons.py, plus JQL tests intest_jira_connector.py.make checkgreen: ruff, mypy, docs check, 2007 passed / 2 skipped.Generated by Claude Code