Skip to content

fix(polling_source): exclude _content_hash from _combine column config (ITL-616) - #259

Merged
eywalker merged 6 commits into
mainfrom
eywalker/itl-616-pollingsource_combine-leaks-_content_hash-into-the-data
Aug 25, 2026
Merged

fix(polling_source): exclude _content_hash from _combine column config (ITL-616)#259
eywalker merged 6 commits into
mainfrom
eywalker/itl-616-pollingsource_combine-leaks-_content_hash-into-the-data

Conversation

@kurodo3

@kurodo3 kurodo3 Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • PollingSource._combine was calling as_table(all_info=True) on both streams before concatenating them. all_info=True includes content_hash=True, which causes ArrowTableStream.as_table() to dynamically append a synthetic _content_hash column.
  • pa.concat_tables then baked _content_hash into the combined table passed to ArrowTableStream.__init__, which stored it as a user data column — corrupting the data schema.
  • On the third fetch (second combine), _validate_combining_schemas detected _content_hash in the accumulated stream's keys but not in the new batch's keys, raising SchemaInconsistencyError.
  • Fix: Added _STREAM_COMBINE_COLUMNS = ColumnConfig(system_tags=True, source=True, context=True) module-level constant and replaced as_table(all_info=True) with as_table(columns=_STREAM_COMBINE_COLUMNS) in _combine. content_hash is intentionally excluded — it is a synthetic output column, never a stored one.

Test Plan

  • Two new regression tests added to TestPollingSourceSchemaValidation:
    • test_sync_three_fetches_no_content_hash_leak — 3 sync iter_data() calls, asserts row accumulation and no _content_hash in data keys/schema
    • test_async_three_fetches_no_content_hash_leak — 3-batch async drain, same assertions via public src.keys() / src.output_schema()
  • Both regression tests confirmed FAIL before fix, PASS after
  • Full polling source suite: 63/63 passed
  • DESIGN_ISSUES.md updated with PS3 entry (status: resolved)

Fixes ITL-616

🤖 Generated with Claude Code

kurodo3 Bot and others added 6 commits August 25, 2026 19:10
…g (ITL-616)

_combine passed all_info=True to as_table(), which triggered content_hash=True
and injected the synthetic _content_hash column into the concatenated table.
ArrowTableStream.__init__ stored it as a data column, corrupting the schema
on the second combine and raising SchemaInconsistencyError on the third fetch.

Add _STREAM_COMBINE_COLUMNS = ColumnConfig(system_tags=True, source=True,
context=True) and use it in place of all_info=True. content_hash is excluded
because it is a synthetic, on-demand output — not a stored column.
…order (ITL-616)

Switch test_async_three_fetches_no_content_hash_leak to call src.keys()
and src.output_schema() instead of accessing the private _accumulated_stream
attribute. Also reorder PS3 metadata block in DESIGN_ISSUES.md to match
the file-wide convention (Status, Severity, Issue then Fix at end of body).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes a schema-corruption bug in PollingSource._combine where calling as_table(all_info=True) caused ArrowTableStream.as_table() to synthesize _content_hash, which then got persisted into the accumulated stream’s stored data schema during pa.concat_tables.

Changes:

  • Introduce a dedicated _STREAM_COMBINE_COLUMNS (ColumnConfig(system_tags=True, source=True, context=True)) and use it in _combine to avoid persisting the synthetic _content_hash column.
  • Add sync + async regression tests covering the “third fetch / second combine” failure mode and asserting _content_hash does not leak into data keys/schema.
  • Document the issue and resolution in DESIGN_ISSUES.md (PS3) and add supporting plan/spec artifacts under superpowers/.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/orcapod/core/sources/polling_source.py Fix _combine to concatenate tables without requesting content_hash (prevents _content_hash from becoming a stored data column).
tests/test_channels/test_polling_source.py Add regression coverage for repeated combines (sync + async) ensuring schema stability and no _content_hash leakage.
DESIGN_ISSUES.md Add PS3 entry documenting the root cause and fix; mark as resolved.
superpowers/specs/2026-08-25-itl-616-polling-source-combine-content-hash-fix.md Spec write-up of the bug mechanism and the chosen fix.
superpowers/plans/2026-08-25-itl-616-polling-source-combine-content-hash-fix.md Implementation plan/checklist for the fix and regression tests.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@kurodo3

kurodo3 Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review, @copilot-pull-request-reviewer! The Copilot review generated no inline comments — no code changes required. The PR is ready for human review.

@eywalker
eywalker merged commit a19b814 into main Aug 25, 2026
12 checks passed
@eywalker
eywalker deleted the eywalker/itl-616-pollingsource_combine-leaks-_content_hash-into-the-data branch August 25, 2026 22:00
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