Skip to content

Implement RFC 0008: Language Reference document, packaging, and export (R-34/R-35/R-36) - #4

Merged
Evgenus merged 8 commits into
mainfrom
r34-language-reference
Jul 18, 2026
Merged

Implement RFC 0008: Language Reference document, packaging, and export (R-34/R-35/R-36)#4
Evgenus merged 8 commits into
mainfrom
r34-language-reference

Conversation

@Evgenus

@Evgenus Evgenus commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Implements RFC 0008 — the author-facing Language Reference: document (R-34), packaging (R-35), and the get_language_reference() export (R-36). All three ship together with the docstring/README consolidation, per the RFC's atomic-sequencing decision.

What changed

R-34 — docs/LANGUAGE.md (new). The template-language reference for authors (human or agent), carrying cross-cutting semantics only: templates & the marker, context & scoping (incl. the variable-visibility table), the NO_CONTENT model, the error taxonomy, expr/call machinery, and composition patterns. No per-entity sections — per-rule/operator/function prose stays in the registration docs, so the document changes only when the language model changes, not when the catalog grows.

Consolidation (move, don't copy — one owner per fact):

  • SPECIFICATION.md §2 reduced to the engine-internal view (walk dispatch, Context copy-on-write invariants, NoContent implementation, error-plumbing contract); §4 collapsed to a pointer plus the retained Recursion budget invariant; §11 points at the reference's worked example; §5 now names LANGUAGE.md as the one hand-written artifact and documents the new export as §5.2.
  • §4's per-rule facts folded into transon/rules.py docstrings (they grow richer): accessor out-of-scope errors, attr's NO_CONTENT-vs-TransformationError split, full map/filter mode semantics, zip/join/file/format edge cases, expr/call empty-values errors — plus the one sanctioned docstring→reference pointer for the shared expr/call application semantics. The set docstring trades its deep scoping model (now reference-owned) for a compact per-rule statement.
  • Transformer class docstring slimmed ~225 → ~75 lines: embedder-only (usage, constructor options, error catching, extending). The pitch/install/comparison content is owned solely by README.md (already there — no README change needed).

R-35 — packaging. transon/resources/LANGUAGE.md ships in the wheel and sdist (hatchling picks it up with zero config change — verified by building and inspecting both). docs/LANGUAGE.md stays the canonical hand-edited source; identity between the two is test-enforced.

R-36 — transon/reference.py. get_language_reference(){reference_version, engine_version, format, content, sections} with REFERENCE_VERSION '1.0', fence-aware deterministic ##-heading splitting, GitHub-style slug ids with collision suffixes, the preamble rule, and a python -m transon.reference CLI. Engine-global (base Transformer only); language facts only.

Reviewer notes

  • Exported content changes, shapes don't (called out in CHANGELOG per the RFC's Sequencing): get_all_docs()['doc'] shrinks to the embedder narrative; per-rule doc text in get_all_docs() and get_editor_metadata()['docs'] grows. Doc text is contractually opaque to the editor; the docs site absorbs this via D-20 (transon-org.github.io, hard dependency of the release).
  • Drift protection is a pinned section-id list in tests/test_reference.py (not catalog-coverage — the RFC deliberately dropped that): editing LANGUAGE.md's section set requires touching the pin and following the reference_version policy. Also tested: sections-concatenation parity, packaging parity via importlib.resources, canonical↔packaged identity, splitter edge cases (no preamble, slug collisions, fenced ##, deeper headings).
  • Canonical↔packaged copy: chose the RFC's committed-copy + identity-test option over build-time force-include — identical behavior in dev/CI/installed layouts; the test fails loudly if the copies diverge.
  • Verified: pytest 392 passed, 99 % coverage (not reduced); python -m transon.docs reports no TBD; scripts/check_roadmap.py consistent; wheel + sdist built and inspected.
  • Bookkeeping: CHANGELOG under [Unreleased]; R-34/35/36 → done with Shipped notes; RFC 0008 + proposals index → Implemented (unreleased). Cross-repo follow-ups (out of scope here): D-20 docs-site migration, transon-authoring reference pin.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added get_language_reference() for offline access to the Language Reference (versioned, deterministic section splitting) plus a CLI to output it as JSON.
  • Documentation
    • Consolidated author-facing language guidance into the exported Language Reference; updated roadmap/spec/RFC 0008 and clarified docs generation/rendering.
  • Bug Fixes
    • map “items” mode now raises a located definition error when items doesn’t evaluate to a list.
    • transform(..., copy_output=True) preserves NO_CONTENT identity, including when nested in copied outputs.
  • Tests
    • Added/expanded coverage for reference structure, deterministic IDs, packaging parity, and NO_CONTENT identity/validation behavior.

Evgenus and others added 2 commits July 18, 2026 01:23
Amend RFC 0008 through review and accept it:

- Consolidation scope extended to the Transformer class docstring and
  README.md (sourcing rule covers all three copies of the semantics).
- Single ownership principle: structure in the catalog, per-entity
  behavior in registration docs (spec §4 facts fold into rule
  docstrings), cross-cutting semantics in LANGUAGE.md, examples in the
  corpus. LANGUAGE.md has no per-entity sections, so it stays stable as
  the catalog grows.
- Drift protection switched from catalog-coverage to a pinned
  section-id test; get_all_docs()['doc'] keeps shape, content shrinks
  to the embedder narrative; atomic one-release sequencing.

Roadmap: new Theme G with R-34 (LANGUAGE.md document), R-35 (package as
package data), R-36 (get_language_reference() versioned export), all
accepted. Docs-site counterpart D-20 (render LANGUAGE.md, README-built
landing, embedding page) recorded as a hard dependency of the release.
Also de-stale the engine-roadmap note in DOCS_SITE_ROADMAP.md
(R-01…R-22 → R-xx).

check_roadmap.py: consistent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…port (R-34/35/36)

R-34: new hand-written docs/LANGUAGE.md — the author-facing, cross-cutting
template-language semantics (evaluation model, scoping, NO_CONTENT model,
error taxonomy, expr/call machinery, composition patterns; no per-entity
sections). Consolidation per the RFC's ownership principle:
- spec §2 reduced to the engine-internal view; §4 collapsed to a pointer
  plus the Recursion budget invariant; §11 points at the reference
- spec §4's per-rule facts folded into the rules.py docstrings (richer):
  accessor scope errors, attr error split, map/filter modes, zip/join/
  file/format edge cases, expr/call empty-values errors + the sanctioned
  pointer to the reference's machinery sections
- Transformer class docstring slimmed to the embedder narrative (usage,
  constructor options, extending); pitch/install/comparison owned by README

R-35: packaged copy transon/resources/LANGUAGE.md ships in wheel and sdist
(hatchling default pickup, verified by building both); identity with the
canonical docs/LANGUAGE.md is test-enforced.

R-36: transon/reference.py get_language_reference() — REFERENCE_VERSION
1.0, fence-aware deterministic heading split, GitHub-style slug ids with
collision suffixes, preamble rule, python -m transon.reference CLI;
spec §5.2 documents the export.

Tests: tests/test_reference.py pins the section-id list (drift
protection), asserts sections-concatenation parity, packaging parity via
importlib.resources, and unit-tests the splitter. 392 passed, 99% cov;
python -m transon.docs reports no TBD; check_roadmap.py consistent.

Bookkeeping: CHANGELOG entry under Unreleased (names the
get_all_docs doc-field content change per Sequencing); R-34/35/36 done
with Shipped notes; RFC 0008 and proposals index moved to Implemented
(unreleased). Docs-site counterpart is D-20 (separate repo).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds RFC 0008’s Template Language Reference, packages it as a resource, exposes versioned sectioned content through transon.reference, updates semantic documentation, fixes two runtime behaviors, and adds export, section-splitting, packaging-parity, and behavior tests.

Changes

Language Reference delivery

Layer / File(s) Summary
Reference contract and documentation
docs/LANGUAGE.md, docs/SPECIFICATION.md, docs/proposals/..., transon/resources/LANGUAGE.md
Defines the author-facing reference, export shape, deterministic section rules, packaging parity, and RFC 0008 implementation status.
Packaged reference export
transon/reference.py
Loads packaged Markdown, derives deterministic top-level sections and unique IDs, returns version and engine metadata, and supports JSON output through python -m transon.reference.
Runtime semantics documentation
transon/rules.py, transon/transformers.py
Expands rule and Transformer documentation with scoping, NO_CONTENT, error, composition, and extension semantics.
Runtime behavior fixes
transon/rules.py, transon/transformers.py, tests/test_invalid_value.py, tests/test_copy_output.py
Rejects non-list map items results with DefinitionError and preserves NO_CONTENT or substitute identity when copying output.
Export and packaging validation
tests/test_reference.py
Validates payload shape, pinned section IDs, content reconstruction, packaged-copy parity, preambles, slug collisions, code fences, and nested headings.
Release and documentation tracking
CHANGELOG.md, docs/ROADMAP.md, docs/DOCS_SITE_ROADMAP.md, docs/proposals/README.md
Records completed reference deliverables, documentation-site migration requirements, changelog entries, and RFC 0008’s implemented/unreleased status.

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

Possibly related PRs

  • transon-org/transon#2: Updates RFC 0008 documentation and roadmap references for the language reference export and packaging contract.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 65.63% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change set: RFC 0008 language reference docs, packaging, and export work.
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 r34-language-reference

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

@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 99.15%. Comparing base (d243e9e) to head (c728598).

Files with missing lines Patch % Lines
transon/reference.py 95.91% 2 Missing ⚠️
transon/transformers.py 85.71% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main       #4      +/-   ##
==========================================
- Coverage   99.35%   99.15%   -0.21%     
==========================================
  Files           7        8       +1     
  Lines        1248     1306      +58     
==========================================
+ Hits         1240     1295      +55     
- Misses          8       11       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

Caution

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

⚠️ Outside diff range comments (1)
docs/proposals/0008-language-reference-export.md (1)

160-169: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Make the concrete export example match the pinned section IDs.

The implemented reference begins with preamble and uses the-no_content-model; this example shows no-content and omits the preamble. Update the example or explicitly label it schematic.

🤖 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/proposals/0008-language-reference-export.md` around lines 160 - 169,
Update the concrete export example to include the initial preamble section and
use the pinned section ID the-no_content-model instead of no-content, preserving
the documented export structure; alternatively, explicitly label the example as
schematic if it is not intended to reflect the implementation.
🤖 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/proposals/0008-language-reference-export.md`:
- Around line 3-5: Update the proposal header’s Status metadata to remove the
future-dated “Implemented (2026-07-18)” and claim that it is already in main;
use the actual landing date if implemented, or retain an appropriate
pre-implementation status until after July 18, 2026.

In `@docs/proposals/README.md`:
- Line 46: Reconcile the RFC 0008 entry’s lifecycle fields in the proposals
index: update the “Implemented” status to the appropriate unreleased/accepted
status while the release remains “unreleased,” or replace “unreleased” with the
actual shipped version if it is released. Keep the lifecycle status and release
value consistent with the documented lifecycle table.

In `@docs/ROADMAP.md`:
- Around line 1030-1037: Correct the acceptance date in the RFC 0008 roadmap
entry so it is not listed as July 18, 2026 before that date occurs. Use the
actual decision date if already accepted, or remove/update the acceptance date
until acceptance is finalized.

In `@docs/SPECIFICATION.md`:
- Around line 413-419: Update the documented export shape in
docs/SPECIFICATION.md lines 413-419 and
docs/proposals/0008-language-reference-export.md lines 173-176 to describe
content as canonical normalized UTF-8 text with LF newlines rather than a
byte-exact original document. Preserve the existing shape, versioning rules, and
requirement that concatenating the ordered sections reproduces normalized
content exactly.
- Around line 426-429: Revise the packaging statement in docs/SPECIFICATION.md
(lines 426-429) to describe only source-tree parity unless CI adds an
install-from-built-wheel/sdist check. In
docs/proposals/0008-language-reference-export.md (lines 147-152), remove the
claim that tests exercise the installed wheel/sdist layout unless such CI
coverage is actually implemented.

In `@transon/reference.py`:
- Around line 84-92: Preserve whitespace-only preambles by changing the preamble
guard in transon/reference.py at lines 84-92 from a stripped-content check to a
direct content check, ensuring every prefix byte is emitted in the preamble
section. Update tests/test_reference.py lines 95-97 to expect both “preamble”
and “first” sections and assert that concatenating their content exactly
reproduces the original input.
- Around line 70-73: Update the Markdown parsing loop in the section-boundary
function to track the active fence delimiter’s character and length rather than
toggling a boolean for every ```-style line. Use the existing _FENCE matcher to
recognize backtick and tilde fences, open only when no fence is active, and
close only with a same-character delimiter of equal or greater length containing
no trailing content; add a regression case covering ## text inside a ~~~ block.

In `@transon/rules.py`:
- Around line 319-327: Update the lazy `map.items` execution path around
`t.walk_param(...)` to validate that each evaluated value is a list before
iterating it. Raise `DefinitionError` for structural parameter mismatches and
`TransformationError` for malformed runtime data, avoiding iteration of
dictionaries or strings and preventing raw `TypeError` leakage.
- Around line 319-327: Update rule_map, rule_expr, and rule_call to validate
mutually exclusive mode parameters during node walking, including lazy dispatch
rather than only when validate=True. Reject overlapping or malformed template
combinations with DefinitionError before selecting a branch, while keeping
_variants accurate for the available modes.

In `@transon/transformers.py`:
- Around line 281-287: Update transform() so copy_output=True does not deepcopy
a top-level Transformer.NO_CONTENT result; return the original sentinel
unchanged while retaining deep-copy behavior for all other results. Add a test
asserting identity with Transformer.NO_CONTENT.

---

Outside diff comments:
In `@docs/proposals/0008-language-reference-export.md`:
- Around line 160-169: Update the concrete export example to include the initial
preamble section and use the pinned section ID the-no_content-model instead of
no-content, preserving the documented export structure; alternatively,
explicitly label the example as schematic if it is not intended to reflect the
implementation.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 674f84ec-2ccd-4845-8bde-071d3b813ad1

📥 Commits

Reviewing files that changed from the base of the PR and between d243e9e and fcf0753.

📒 Files selected for processing (12)
  • CHANGELOG.md
  • docs/DOCS_SITE_ROADMAP.md
  • docs/LANGUAGE.md
  • docs/ROADMAP.md
  • docs/SPECIFICATION.md
  • docs/proposals/0008-language-reference-export.md
  • docs/proposals/README.md
  • tests/test_reference.py
  • transon/reference.py
  • transon/resources/LANGUAGE.md
  • transon/rules.py
  • transon/transformers.py

Comment thread docs/proposals/0008-language-reference-export.md Outdated
Comment thread docs/proposals/README.md Outdated
Comment thread docs/ROADMAP.md
Comment thread docs/SPECIFICATION.md Outdated
Comment thread docs/SPECIFICATION.md Outdated
Comment thread transon/reference.py Outdated
Comment thread transon/reference.py
Comment thread transon/rules.py
Comment thread transon/transformers.py
Code fixes (7 of 10 findings confirmed):
- reference.py: CommonMark-correct fence tracking (backtick AND tilde
  fences; closers must match the opening character, be at least as long,
  and carry no trailing content) — a heading inside a ~~~ block is no
  longer treated as a section boundary; regression tests added
- reference.py: whitespace-only prefixes are preserved as the preamble
  section (previously dropped by .strip(), silently breaking the
  sections-concatenation parity invariant); test updated to assert parity
- rules.py: map `items` mode validates the evaluated value is a list and
  raises a located DefinitionError (matches the expr/call `values`
  precedent) instead of iterating dict keys / string chars or leaking a
  raw TypeError; regression test + changelog entry
- transformers.py: transform(copy_output=True) no longer deepcopies the
  NO_CONTENT branch — sentinel identity is preserved and a caller-owned
  no_content substitute is returned as-is; identity tests + changelog

Doc fixes:
- "byte-exact" wording corrected to canonical normalized text (UTF-8, LF)
  in spec §5.2 and the RFC
- packaging-parity claims scoped honestly to source-tree parity (wheel/
  sdist inclusion verified by building distributions at release)
- RFC export example now matches the implemented section ids (preamble,
  the-no_content-model); preamble rule wording covers whitespace-only
  prefixes
- RFC status no longer claims "in main"; proposals index Shipped column
  is "—" until a release names the version

Declined with reasons (posted on the PR): the two "future date" findings
(2026-07-18 is the actual decision/implementation date) and walk-time
mutually-exclusive-mode enforcement (explicitly rejected in the recorded
R-04 decision — option 1, opt-in validate(), was chosen over walk-time
enforcement precisely because the latter is breaking).

397 passed; no TBD; check_roadmap consistent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Evgenus

Evgenus commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the CodeRabbit review in 830acfb. Disposition of all 10 findings:

Fixed (7):

  • Tilde fences (reference.py) — proper CommonMark fence tracking: backtick and tilde fences; a closer must match the opening character, be at least as long, and carry no trailing content. Regression tests for ~~~ fences and mismatched/longer closers.
  • Whitespace-only preamble (reference.py) — any non-empty prefix is now emitted as the preamble section, so sections-concatenation parity holds unconditionally; the test that locked in the old behavior now asserts parity.
  • map.items non-list result (rules.py) — now a located DefinitionError (matches the existing expr/call values precedent) instead of iterating dict keys/string chars or leaking TypeError. Regression test + CHANGELOG entry (behavior change, flagged per project rules).
  • copy_output vs NO_CONTENT (transformers.py) — the sentinel branch is never deep-copied: identity preserved for no_content=Transformer.NO_CONTENT, and a caller-supplied substitute is returned as-is (it cannot alias the input). Identity tests + CHANGELOG entry.
  • "byte-exact" wording — spec §5.2 and the RFC now say canonical normalized text (UTF-8, LF).
  • Packaging-parity overclaim — spec + RFC now scope the test to source-tree parity; wheel/sdist inclusion is verified by building the distributions at release.
  • RFC example / lifecycle drift — export example now shows the real pinned ids (preamble, the-no_content-model); RFC status no longer claims "in main"; proposals index Shipped is until a release names the version.

Declined (3), with reasons:

  • Two "future date" findings (RFC status, roadmap acceptance date): 2026-07-18 is the actual decision/implementation date — the review bot's clock appears to be a day behind. No change.
  • Walk-time mutually-exclusive-mode enforcement (rule_map/rule_expr/rule_call): this exact trade-off is a recorded project decision — Roadmap R-04 chose option 1 (opt-in validate()/validate=True catches ambiguous parameter combinations statically) and explicitly noted walk-time enforcement is breaking for templates carrying a redundant ignored parameter. The docstrings' "mutually exclusive" statements are the contract validate() enforces; changing lazy dispatch would be a silent behavior change contrary to the roadmap decision. No change.

397 tests pass; python -m transon.docs reports no TBD; scripts/check_roadmap.py consistent.

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

Caution

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

⚠️ Outside diff range comments (1)
transon/rules.py (1)

314-327: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Skip NO_CONTENT before enforcing the list shape.

The docstring promises that NO_CONTENT results are skipped, but the new guard rejects the sentinel because it is not a list. A conditional items template can therefore abort the entire map instead of omitting the current element. Check items is t.NO_CONTENT first, then reject other non-list values.

Proposed fix
             items = t.walk_param(t_items, sub_context, 'items')
+            if items is t.NO_CONTENT:
+                continue
             if not isinstance(items, list):
                 t.definition_error(
                     '`items` must evaluate to a list for `map` rule'
                 )

As per path instructions, NO_CONTENT inputs must retain their documented skipping semantics.

Also applies to: 342-347

🤖 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 `@transon/rules.py` around lines 314 - 327, The map transformation’s items-mode
validation rejects NO_CONTENT before honoring its documented skip behavior. In
the items handling logic, check whether the evaluated result is NO_CONTENT and
omit that element first; only enforce the list type for other results,
preserving flattening for valid lists.

Source: Path instructions

🧹 Nitpick comments (1)
tests/test_invalid_value.py (1)

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

Cover all invalid shapes and the location contract.

This test covers only a dict and matches only the message body. Parameterize dict, string, and scalar results, then assert the formatted template-path suffix as well. That protects against accidental string iteration, raw TypeError, and lost error-location reporting.

As per path instructions, engine-mechanics tests should assert the exception type and template-path location, with parametrization where practical.

🤖 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_invalid_value.py` around lines 36 - 44, Expand
test_map_items_non_list_result to be parametrized over dict, string, and scalar
item results, while preserving the DefinitionError assertion. Update the match
to verify both the existing “items must evaluate to a list” message and the
formatted template-path suffix, ensuring invalid shapes report the correct
location.

Source: Path instructions

🤖 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 `@transon/transformers.py`:
- Around line 731-739: Ensure the NO_CONTENT singleton preserves identity when
nested inside copied containers, not only when returned directly from the
surrounding result branch. Update the NoContent deepcopy behavior or the copy
boundary used by the relevant transformer so copy.deepcopy leaves this sentinel
unchanged, and add a regression test covering nested list or dictionary values
with identity assertions.

---

Outside diff comments:
In `@transon/rules.py`:
- Around line 314-327: The map transformation’s items-mode validation rejects
NO_CONTENT before honoring its documented skip behavior. In the items handling
logic, check whether the evaluated result is NO_CONTENT and omit that element
first; only enforce the list type for other results, preserving flattening for
valid lists.

---

Nitpick comments:
In `@tests/test_invalid_value.py`:
- Around line 36-44: Expand test_map_items_non_list_result to be parametrized
over dict, string, and scalar item results, while preserving the DefinitionError
assertion. Update the match to verify both the existing “items must evaluate to
a list” message and the formatted template-path suffix, ensuring invalid shapes
report the correct location.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1ef23f84-5f46-40b9-8cf1-c263852ad2bd

📥 Commits

Reviewing files that changed from the base of the PR and between fcf0753 and 830acfb.

📒 Files selected for processing (10)
  • CHANGELOG.md
  • docs/SPECIFICATION.md
  • docs/proposals/0008-language-reference-export.md
  • docs/proposals/README.md
  • tests/test_copy_output.py
  • tests/test_invalid_value.py
  • tests/test_reference.py
  • transon/reference.py
  • transon/rules.py
  • transon/transformers.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • transon/reference.py
  • docs/proposals/0008-language-reference-export.md
  • docs/SPECIFICATION.md

Comment thread transon/transformers.py
NoContent now defines __copy__/__deepcopy__ returning itself, so a
sentinel kept inside a copied container (a literal template list holding
a missing lookup) survives transform(copy_output=True) with identity
intact — the earlier fix only covered the top-level branch. Regression
test + changelog note extended. (CodeRabbit follow-up on PR 4)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@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)
transon/transformers.py (1)

740-746: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Apply copy_output to mutable no_content substitutions.

no_content is caller-supplied and may be data itself or a mutable subobject. Returning it unchanged with copy_output=True can therefore preserve aliases to the input, violating the documented copy boundary. Keep the raw NO_CONTENT identity exception, but deep-copy other substitutions when requested.

As per path instructions, copy_output=True must deep-copy the result at the boundary.

Proposed fix
             if no_content is self.NO_CONTENT:
                 return result
-            return no_content
+            return copy.deepcopy(no_content) if copy_output else no_content
🤖 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 `@transon/transformers.py` around lines 740 - 746, Update the no-content
handling in the transformer method around the result check: retain the
identity-based fast path for the raw NO_CONTENT sentinel, but when returning a
caller-supplied no_content substitution, deep-copy it whenever copy_output is
enabled. Preserve the existing direct return behavior when copying is disabled.

Source: Path instructions

🤖 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 `@transon/transformers.py`:
- Around line 740-746: Update the no-content handling in the transformer method
around the result check: retain the identity-based fast path for the raw
NO_CONTENT sentinel, but when returning a caller-supplied no_content
substitution, deep-copy it whenever copy_output is enabled. Preserve the
existing direct return behavior when copying is disabled.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b43ca752-550a-4df7-b45c-b00b75a3a0b4

📥 Commits

Reviewing files that changed from the base of the PR and between 830acfb and 58397f7.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • tests/test_copy_output.py
  • transon/transformers.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/test_copy_output.py
  • CHANGELOG.md

Invert the R-35 ownership: transon/resources/LANGUAGE.md is now the
canonical, hand-edited, single copy (the file that ships in the wheel/
sdist is the file you edit — same rule as per-rule docs living in
rules.py); docs/LANGUAGE.md is reduced to a pointer for docs/
discoverability. Drops the mirror + identity test (no sync step exists
to forget) while keeping the packaging-parity, section-pin, and split
tests. RFC 0008 Deliverable 2, spec (layout table, section banners,
5.2), roadmap Shipped notes, CHANGELOG, D-20, and the class-docstring
link all repointed at the canonical path.

398 passed; check_roadmap consistent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@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)
tests/test_reference.py (1)

64-77: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Move this to an installed-artifact test. get_language_reference() and packaged both read transon/resources/LANGUAGE.md from the source tree in a checkout, so this still passes if the wheel or sdist drops or changes the packaged file. Run it against an installed wheel/sdist in CI, or rename it so it only claims source/resource parity.

🤖 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_reference.py` around lines 64 - 77, Rename
test_packaged_resource_is_served to describe source/resource parity, or move it
into an installed-artifact test that runs against a built and installed wheel or
sdist. Ensure get_language_reference() and the importlib.resources lookup
resolve the installed package artifact so the test detects missing or altered
packaged resources.

Source: Path instructions

🤖 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 `@tests/test_reference.py`:
- Around line 64-77: Rename test_packaged_resource_is_served to describe
source/resource parity, or move it into an installed-artifact test that runs
against a built and installed wheel or sdist. Ensure get_language_reference()
and the importlib.resources lookup resolve the installed package artifact so the
test detects missing or altered packaged resources.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 18130d52-4db3-48dd-a391-66b2c02a1419

📥 Commits

Reviewing files that changed from the base of the PR and between 58397f7 and 7a97ad9.

📒 Files selected for processing (8)
  • CHANGELOG.md
  • docs/DOCS_SITE_ROADMAP.md
  • docs/LANGUAGE.md
  • docs/ROADMAP.md
  • docs/SPECIFICATION.md
  • docs/proposals/0008-language-reference-export.md
  • tests/test_reference.py
  • transon/transformers.py
🚧 Files skipped from review as they are similar to previous changes (5)
  • docs/ROADMAP.md
  • docs/SPECIFICATION.md
  • docs/proposals/0008-language-reference-export.md
  • transon/transformers.py
  • CHANGELOG.md

Decision (2026-07-18): SPECIFICATION.md remains the single, complete
engine contract. Restore the original section 2 (core concepts incl. the
scoping table and full NO_CONTENT/error-model statements), section 4
(full per-rule/operator/function reference, 4.1-4.8 incl. the Recursion
budget), and section 11 (data-flow example) from the pre-PR spec —
keeping the additions made since (error-plumbing contract note, the new
map.items non-list fact in 2.4/4.4).

The duplication with LANGUAGE.md and the registration docs is deliberate
and banner-flagged at sections 2 and 4: update all surfaces in the same
change. RFC 0008 amended accordingly (sourcing rule records the
exception; ownership principle scoped to consumer channels; non-goal
reworded; Amended header updated); roadmap R-34 Shipped note and
CHANGELOG aligned.

398 passed; check_roadmap consistent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

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

Caution

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

⚠️ Outside diff range comments (2)
docs/SPECIFICATION.md (2)

633-640: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Specify the sections[] item shape and fence rules.
§5.2 should define each section’s fields (id, title, heading_level, content) and the preamble values explicitly. It should also spell out the fence delimiters (``` / ~~~, matching opener/closer semantics) so consumers split the export the same way.

🤖 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/SPECIFICATION.md` around lines 633 - 640, Update §5.2 to explicitly
define the sections[] item shape with id, title, heading_level, and content
fields, including the exact preamble values. Document fenced-code handling in
the section-splitting rules: recognize ``` and ~~~ delimiters, require matching
opener and closer characters, and keep headings inside fences within the
enclosing section.

Source: Path instructions


800-803: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Describe zip rows as lists, not tuples.

§4.4 and transon/rules.py state that zip returns lists, but this example says each pair becomes a tuple. Replace “tuple” with “array” or “list” to match the implementation.

🤖 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/SPECIFICATION.md` around lines 800 - 803, Update the zip example in the
specification to describe each pair as a list or array instead of a tuple,
matching the documented and implemented zip result while preserving the
surrounding context and mapping behavior.
🤖 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/SPECIFICATION.md`:
- Around line 49-56: Correct the decision date in the duplication notes near the
specification section and the corresponding note around the registration
documentation reference: replace the future July 18, 2026 date with the actual
July 17, 2026 date, or remove the date from both notes until the decision
occurs.

---

Outside diff comments:
In `@docs/SPECIFICATION.md`:
- Around line 633-640: Update §5.2 to explicitly define the sections[] item
shape with id, title, heading_level, and content fields, including the exact
preamble values. Document fenced-code handling in the section-splitting rules:
recognize ``` and ~~~ delimiters, require matching opener and closer characters,
and keep headings inside fences within the enclosing section.
- Around line 800-803: Update the zip example in the specification to describe
each pair as a list or array instead of a tuple, matching the documented and
implemented zip result while preserving the surrounding context and mapping
behavior.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cf65328d-0710-4964-a6c5-2cc48cce9464

📥 Commits

Reviewing files that changed from the base of the PR and between 7a97ad9 and c6eb9f9.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • docs/ROADMAP.md
  • docs/SPECIFICATION.md
  • docs/proposals/0008-language-reference-export.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • docs/ROADMAP.md
  • CHANGELOG.md
  • docs/proposals/0008-language-reference-export.md

Comment thread docs/SPECIFICATION.md
Evgenus and others added 2 commits July 18, 2026 02:56
The doc field is rendered as markdown by the docs site; a Sphinx-style
:class: role would show literally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The lifecycle table said Implemented means shipped in a named release,
which contradicted RFC 0008 being Implemented with roadmap items done
but no tag yet (the roadmap term mapping requires Implemented <-> done).
Implemented now means implementation merged; the Shipped column names
the version once the release is tagged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Evgenus
Evgenus merged commit c0d453f into main Jul 18, 2026
6 of 8 checks passed
@Evgenus
Evgenus deleted the r34-language-reference branch July 18, 2026 00:09
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