Skip to content

Feature/schema synchronization and export - #41

Merged
miroslavpojer merged 8 commits into
masterfrom
feature/schema-synchronization-and-export
Jun 30, 2026
Merged

Feature/schema synchronization and export#41
miroslavpojer merged 8 commits into
masterfrom
feature/schema-synchronization-and-export

Conversation

@miroslavpojer

@miroslavpojer miroslavpojer commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements schema synchronization and export functionality for doc-issues.json, adds acceptance criteria handling across the pipeline, and fixes producer metadata references.

Release Notes:

  • New: Schema export for doc-issues.jsoncollector_gh can now export a versioned JSON Schema (doc-issues-v1.0.0-schema.json) and validates documents against it at runtime.
  • New: SCHEMA_SYNC.md guide documenting the schema versioning and synchronization workflow for collector_gh.
  • Fix: Renamed metadata.generatormetadata.producer across code, tests, fixtures, and documentation to align with the canonical schema field name.
  • Feat: Acceptance criteria field (acceptance_criteria) added to the doc-issues schema, collector_gh models/parser, datasets_pdf models, and normalize_issues builder — full end-to-end propagation.
  • Schema: Added "format": "date-time" constraint to generated_at in pdf_ready_v1.schema.json for strict ISO 8601 validation.

Summary by CodeRabbit

  • New Features
    • Added support for structured issue data using items with producer metadata, including structured acceptance-criteria and section formatting.
    • Added JSON Schema export plus new schema documentation for downstream validation.
  • Bug Fixes
    • Updated CLI error messages and compatibility warnings to reference the new producer metadata fields.
    • Improved normalization behavior for structured inputs and missing/partial data.
  • Documentation
    • Refreshed architecture, contracts, troubleshooting, and workflow docs to match the new data format.
  • Chores
    • Standardized tooling defaults and lint formatting; updated .gitignore; tightened a PDF-ready schema datetime format.

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@miroslavpojer, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 52 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b2b4627b-3b38-4578-9910-ebd3a10be4c7

📥 Commits

Reviewing files that changed from the base of the PR and between 5f208d6 and fa289cd.

📒 Files selected for processing (2)
  • packages/adapters/collector_gh/src/living_doc_adapter_collector_gh/compatibility.py
  • packages/adapters/collector_gh/tests/test_compatibility.py

Walkthrough

This PR renames collector metadata from generator to producer, changes payloads from issues maps to items arrays, adds structured acceptance-criteria models and schema export support, and updates the CLI, normalize-issues service, tests, fixtures, docs, and tooling to match.

Changes

Schema, parser, and downstream normalization updates

Layer / File(s) Summary
Data contracts and schema artifacts
packages/adapters/collector_gh/src/.../models.py, packages/datasets_pdf/src/.../pdf_ready/v1/models.py, packages/adapters/collector_gh/schemas/doc-issues-v1.0.0-schema.json, packages/datasets_pdf/schemas/pdf_ready_v1.schema.json
AdapterItemAcceptanceCriterion and AcceptanceCriterion are added, AdapterItem and Sections gain structured list fields, the collector JSON Schema is added, and Meta.generated_at gains format: "date-time".
Compatibility and producer detection
packages/adapters/collector_gh/src/.../compatibility.py, .../detector.py
CONFIRMED_MIN is lowered to 0.1.0, SCHEMA_VERSION is added, INVALID_VERSION now points to metadata.producer.version, and detector logic reads metadata.producer.name/version.
Collector parser rewrite
packages/adapters/collector_gh/src/.../parser.py
The parser now validates metadata and items, extracts metadata from producer/run/source, reconstructs bodies from structured fields, parses item acceptance criteria, and aggregates item-level failures.
Schema export module and package exports
packages/adapters/collector_gh/src/.../schema_export.py, packages/adapters/collector_gh/src/.../__init__.py
A new schema export module writes versioned JSON Schema output, exposes schema-version helpers, and re-exports the new schema symbols from the package entry point.
PDF-ready section structuring
packages/services/normalize_issues/src/.../builder.py, packages/datasets_pdf/tests/...
The normalize-issues builder now parses markdown into lists or structured acceptance criteria and prefers structured item fields when building PDF-ready sections; the PDF-ready model tests are updated accordingly.

CLI, fixtures, and test updates

Layer / File(s) Summary
CLI, fixtures, and test updates
apps/cli/src/.../normalize_issues.py, apps/cli/tests/..., packages/adapters/collector_gh/tests/fixtures/..., packages/adapters/collector_gh/tests/test_*.py, packages/services/normalize_issues/tests/..., tests/fixtures/...
CLI error guidance, collector and service fixtures, golden outputs, and unit/integration tests are updated to the producer metadata and items-array schema, including the new structured section outputs.

Docs, schema-sync guide, and tooling

Layer / File(s) Summary
Docs, schema-sync guide, and tooling
docs/architecture.md, docs/contracts.md, docs/cookbooks/normalize-issues.md, docs/troubleshooting.md, packages/adapters/collector_gh/SCHEMA_SYNC.md, packages/adapters/collector_gh/schemas/README.md, Makefile, .gitignore, */pyproject.toml
Architecture, contracts, cookbook, troubleshooting, schema-sync, and schema README docs are updated to producer metadata; the Makefile default switches to python3; .gitignore adds two generated files; and Pylint max-line-length is set to 120 in the affected project configs.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • tmikula-dev

Poem

🐇 I hop through schemas, neat and new,
producer shines where generator once grew.
An items parade now steps in line,
With structured criteria looking fine.
The rabbit nods: “All fields align!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and matches the main change: schema sync/export work.
Description check ✅ Passed It includes a summary and release notes, but omits the template's Overview and Related sections.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/schema-synchronization-and-export

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.

…rove clarity

Update parser tests to reflect changes in data structure and enhance error handling

Add Pylint configuration for max line length in pyproject.toml files across multiple packages

Refactor acceptance criteria and business value structures in PDF dataset tests for consistency

Update normalize issues service tests to align with new data structure and improve clarity

Add unit tests for schema export functionality to ensure correct schema versioning and path resolution
@miroslavpojer
miroslavpojer marked this pull request as ready for review June 29, 2026 16:01

@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: 6

Caution

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

⚠️ Outside diff range comments (2)
packages/adapters/collector_gh/SCHEMA_SYNC.md (1)

188-188: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Fix broken relative link to docs/contracts.md.

From packages/adapters/collector_gh/SCHEMA_SYNC.md, the repository root is three levels up (../../../), not two. The current link ../../docs/contracts.md resolves to packages/docs/contracts.md, which does not exist.

-- **Input Contract Docs:** [../../docs/contracts.md](../../docs/contracts.md#input-contract-doc-issuesjson)
+- **Input Contract Docs:** [../../../docs/contracts.md](../../../docs/contracts.md#input-contract-doc-issuesjson)
🤖 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 `@packages/adapters/collector_gh/SCHEMA_SYNC.md` at line 188, The relative link
to docs/contracts.md in SCHEMA_SYNC.md is resolving to the wrong location.
Update the markdown link so it points from
packages/adapters/collector_gh/SCHEMA_SYNC.md to the repository-root
docs/contracts.md using the correct three-level relative path, and verify the
reference still works from that document.
docs/cookbooks/normalize-issues.md (1)

125-140: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Update JSON example to use producer key.

The adapter mapping prose at Line 125 correctly states metadata.producer.* → audit.producer.*, but the input JSON example at Lines 134-140 still shows "generator" instead of "producer". Since fixtures and the collector output were updated to use producer across the stack, this example will confuse users.

 {
   "metadata": {
-    "generator": {
+    "producer": {
       "name": "AbsaOSS/living-doc-collector-gh",
       "version": "1.2.0",
       "build": "abc123"
     }
   }
 }
🤖 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/cookbooks/normalize-issues.md` around lines 125 - 140, The JSON example
in the normalize-issues cookbook still uses the old metadata.generator key even
though the mapping and collector now use metadata.producer; update the example
under the audit mapping section to match the producer terminology so it stays
consistent with the documented transform. Use the surrounding mapping text and
the example block in normalize-issues.md as the location cues.
🧹 Nitpick comments (3)
packages/adapters/collector_gh/tests/test_parser.py (1)

248-248: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Move these imports to module scope.

The new test methods import inside the function bodies, and the local parse import is redundant because this module already calls parse elsewhere. Import _build_body_from_structured once at the top of the file and drop the in-method imports.

As per coding guidelines, "Place all Python imports at the top of the file (no imports inside methods/functions)".

♻️ Proposed fix
+from living_doc_adapter_collector_gh.parser import _build_body_from_structured
...
-        from living_doc_adapter_collector_gh.parser import _build_body_from_structured
...
-        from living_doc_adapter_collector_gh.parser import _build_body_from_structured
...
-        from living_doc_adapter_collector_gh.parser import _build_body_from_structured
...
-        from living_doc_adapter_collector_gh.parser import parse

Also applies to: 271-271, 279-279, 286-286

🤖 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 `@packages/adapters/collector_gh/tests/test_parser.py` at line 248, The new
tests in test_parser.py are importing _build_body_from_structured and parse
inside test methods, which violates the module-level import guideline and makes
the local parse import redundant. Move the needed imports to the top of the file
alongside the existing test imports, then remove the in-method imports from the
affected test cases while keeping the test logic in the same functions.

Source: Coding guidelines

packages/adapters/collector_gh/src/living_doc_adapter_collector_gh/schema_export.py (2)

52-60: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Deduplicate the schema version constant.

1.0.0 is hard-coded here twice, while compatibility.py already exposes SCHEMA_VERSION. These copies will drift on the next schema bump, and then the exported filename, embedded $schema_version, and public API can disagree.

Suggested refactor
 import json
 from pathlib import Path
 
+from living_doc_adapter_collector_gh.compatibility import SCHEMA_VERSION
 from living_doc_adapter_collector_gh.models import AdapterResult
@@
-    schema["$schema_version"] = "1.0.0"
+    schema["$schema_version"] = SCHEMA_VERSION
@@
-    return "1.0.0"
+    return SCHEMA_VERSION

Also applies to: 71-81

🤖 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
`@packages/adapters/collector_gh/src/living_doc_adapter_collector_gh/schema_export.py`
around lines 52 - 60, The schema version is duplicated in the schema export
flow, which can cause the embedded $schema_version and generated filename to
drift from the public API. Update schema_export.py to use the single source of
truth from compatibility.py (SCHEMA_VERSION) in the schema_export logic,
including the AdapterResult.model_json_schema() export and the doc-issues
filename built from get_schema_version(), so both values stay consistent when
the version changes.

64-66: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Move CLI output to logging and keep imports at module top.

This new file uses print() for status output and imports sys inside the __main__ block. As per coding guidelines, **/*.py: Use logging, not print in Python code; Place all Python imports at the top of the file (no imports inside methods/functions).

Suggested refactor
 import json
+import logging
+import sys
 from pathlib import Path
 
 from living_doc_adapter_collector_gh.models import AdapterResult
 
+logger = logging.getLogger(__name__)
@@
-    print(f"Schema exported to: {output_file}")
+    logger.info("Schema exported to: %s", output_file)
@@
-if __name__ == "__main__":
-    import sys
-
+if __name__ == "__main__":
@@
-        print(f"Default location: {get_default_schema_path() / f'doc-issues-v{get_schema_version()}-schema.json'}")
+        logger.info(
+            "Default location: %s",
+            get_default_schema_path() / f"doc-issues-v{get_schema_version()}-schema.json",
+        )

Also applies to: 84-93

🤖 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
`@packages/adapters/collector_gh/src/living_doc_adapter_collector_gh/schema_export.py`
around lines 64 - 66, The CLI status output in schema_export.py still uses
print() and sys is imported inside the __main__ block, both of which violate the
Python guidelines. Update the module to use a logger for the “Schema
exported”/usage messages instead of print, and move any sys import to the
top-level imports alongside the rest of the module’s imports. Keep the changes
centered around the schema export entrypoint and its __main__ handling so the
behavior stays the same without inline imports or stdout logging.

Source: Coding guidelines

🤖 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/cookbooks/normalize-issues.md`:
- Around line 62-71: The example in normalize-issues.md still uses the old
metadata.generator reference in the auto-detection snippet; update the detection
logic in the code block to use metadata.producer.name so it matches the
documented field and the current implementation. Keep the surrounding example
and the CollectorGhAdapter check unchanged, and make sure any related wording in
the same section consistently refers to producer rather than generator.

In `@packages/adapters/collector_gh/SCHEMA_SYNC.md`:
- Line 43: The compatibility range documented in SCHEMA_SYNC.md is inconsistent
with the CONFIRMED_MIN constant in compatibility.py. Update the narrative near
the Producer Compatibility Range reference to match the actual minimum version
used by CONFIRMED_MIN, or change CONFIRMED_MIN in compatibility.py if the
intended floor is 1.0.0. Verify both the documentation and the constant reflect
the same supported range.

In
`@packages/adapters/collector_gh/src/living_doc_adapter_collector_gh/detector.py`:
- Around line 45-50: Reject non-string producer versions in extract_version so
it matches the str contract: in detector.py, the extract_version function should
validate that payload["metadata"]["producer"]["version"] is actually a string
before returning it, not just truthy. Keep the existing AdapterError handling,
but if the value is missing, empty, or not a string, raise an AdapterError from
extract_version rather than returning an int or other type.

In
`@packages/adapters/collector_gh/src/living_doc_adapter_collector_gh/models.py`:
- Around line 22-23: The module docs for the schema export example are
misleading because `schema_export` does not print the schema JSON to stdout;
update the example in `models.py` to match the actual behavior of
`schema_export.py` and `schema_export` so it shows the correct way to generate
the schema file without redirecting stdout. Make sure the documentation clearly
reflects that the command writes the artifact directly and only emits status
output, so readers can locate and run the export path correctly.

In
`@packages/adapters/collector_gh/src/living_doc_adapter_collector_gh/parser.py`:
- Around line 183-193: Validate raw_ac as a list of dict-like items before
building structured_ac in parser.py’s parse flow; if acceptance_criteria is
missing, keep it None, but if it is present and not a list (or contains non-dict
entries), raise a per-item validation error instead of iterating it. In the
AdapterItemAcceptanceCriterion mapping, require description rather than
defaulting it to an empty string so malformed criteria are surfaced by parse()’s
item-level error handling. Use the raw_ac/structured_ac conversion block and
AdapterItemAcceptanceCriterion construction as the main points to update.

In `@packages/datasets_pdf/schemas/pdf_ready_v1.schema.json`:
- Around line 97-101: The PDF-ready schema is out of sync with the updated
models, so regenerate the schema from the current PDF-ready model definitions
rather than keeping the old nullable markdown string shapes. Update the schema
fields that correspond to Sections.business_value, preconditions, and
acceptance_criteria to match the structured list/object types used by
pdf_ready_v1 models and the normalize_issues builder, and ensure the generated
schema reflects the new nested structure instead of legacy nullable strings.

---

Outside diff comments:
In `@docs/cookbooks/normalize-issues.md`:
- Around line 125-140: The JSON example in the normalize-issues cookbook still
uses the old metadata.generator key even though the mapping and collector now
use metadata.producer; update the example under the audit mapping section to
match the producer terminology so it stays consistent with the documented
transform. Use the surrounding mapping text and the example block in
normalize-issues.md as the location cues.

In `@packages/adapters/collector_gh/SCHEMA_SYNC.md`:
- Line 188: The relative link to docs/contracts.md in SCHEMA_SYNC.md is
resolving to the wrong location. Update the markdown link so it points from
packages/adapters/collector_gh/SCHEMA_SYNC.md to the repository-root
docs/contracts.md using the correct three-level relative path, and verify the
reference still works from that document.

---

Nitpick comments:
In
`@packages/adapters/collector_gh/src/living_doc_adapter_collector_gh/schema_export.py`:
- Around line 52-60: The schema version is duplicated in the schema export flow,
which can cause the embedded $schema_version and generated filename to drift
from the public API. Update schema_export.py to use the single source of truth
from compatibility.py (SCHEMA_VERSION) in the schema_export logic, including the
AdapterResult.model_json_schema() export and the doc-issues filename built from
get_schema_version(), so both values stay consistent when the version changes.
- Around line 64-66: The CLI status output in schema_export.py still uses
print() and sys is imported inside the __main__ block, both of which violate the
Python guidelines. Update the module to use a logger for the “Schema
exported”/usage messages instead of print, and move any sys import to the
top-level imports alongside the rest of the module’s imports. Keep the changes
centered around the schema export entrypoint and its __main__ handling so the
behavior stays the same without inline imports or stdout logging.

In `@packages/adapters/collector_gh/tests/test_parser.py`:
- Line 248: The new tests in test_parser.py are importing
_build_body_from_structured and parse inside test methods, which violates the
module-level import guideline and makes the local parse import redundant. Move
the needed imports to the top of the file alongside the existing test imports,
then remove the in-method imports from the affected test cases while keeping the
test logic in the same functions.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4c00090f-c19a-484a-a2cc-7b9c70422a66

📥 Commits

Reviewing files that changed from the base of the PR and between f821093 and 54e67ca.

📒 Files selected for processing (38)
  • .gitignore
  • Makefile
  • apps/cli/pyproject.toml
  • apps/cli/src/living_doc_cli/commands/normalize_issues.py
  • apps/cli/tests/integration/test_cli_invocation.py
  • apps/cli/tests/test_cli.py
  • docs/architecture.md
  • docs/contracts.md
  • docs/cookbooks/normalize-issues.md
  • docs/troubleshooting.md
  • packages/adapters/collector_gh/SCHEMA_SYNC.md
  • packages/adapters/collector_gh/pyproject.toml
  • packages/adapters/collector_gh/schemas/README.md
  • packages/adapters/collector_gh/schemas/doc-issues-v1.0.0-schema.json
  • packages/adapters/collector_gh/src/living_doc_adapter_collector_gh/__init__.py
  • packages/adapters/collector_gh/src/living_doc_adapter_collector_gh/compatibility.py
  • packages/adapters/collector_gh/src/living_doc_adapter_collector_gh/detector.py
  • packages/adapters/collector_gh/src/living_doc_adapter_collector_gh/models.py
  • packages/adapters/collector_gh/src/living_doc_adapter_collector_gh/parser.py
  • packages/adapters/collector_gh/src/living_doc_adapter_collector_gh/schema_export.py
  • packages/adapters/collector_gh/tests/fixtures/collector_v1.0.0/input/doc-issues.json
  • packages/adapters/collector_gh/tests/fixtures/collector_v1.2.0/input/doc-issues.json
  • packages/adapters/collector_gh/tests/test_compatibility.py
  • packages/adapters/collector_gh/tests/test_detector.py
  • packages/adapters/collector_gh/tests/test_parser.py
  • packages/adapters/collector_gh/tests/test_schema_export.py
  • packages/core/pyproject.toml
  • packages/datasets_pdf/pyproject.toml
  • packages/datasets_pdf/schemas/pdf_ready_v1.schema.json
  • packages/datasets_pdf/src/living_doc_datasets_pdf/pdf_ready/v1/models.py
  • packages/datasets_pdf/tests/test_pdf_ready_models.py
  • packages/services/normalize_issues/pyproject.toml
  • packages/services/normalize_issues/src/living_doc_service_normalize_issues/builder.py
  • packages/services/normalize_issues/tests/fixtures/golden/expected_output.json
  • packages/services/normalize_issues/tests/fixtures/golden/input.json
  • packages/services/normalize_issues/tests/integration/test_golden_files.py
  • packages/services/normalize_issues/tests/test_builder.py
  • packages/services/normalize_issues/tests/test_service.py

Comment thread docs/cookbooks/normalize-issues.md
Comment thread packages/adapters/collector_gh/SCHEMA_SYNC.md
Comment thread packages/datasets_pdf/schemas/pdf_ready_v1.schema.json
… criteria, business value, and preconditions; enhance readability and maintainability.
@miroslavpojer
miroslavpojer merged commit cde5c76 into master Jun 30, 2026
5 checks passed
@miroslavpojer
miroslavpojer deleted the feature/schema-synchronization-and-export branch June 30, 2026 07:33
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