Implement RFC 0008: Language Reference document, packaging, and export (R-34/R-35/R-36) - #4
Conversation
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>
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds RFC 0008’s Template Language Reference, packages it as a resource, exposes versioned sectioned content through ChangesLanguage Reference delivery
Estimated code review effort: 3 (Moderate) | ~30 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Codecov Report❌ Patch coverage is
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. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
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 winMake the concrete export example match the pinned section IDs.
The implemented reference begins with
preambleand usesthe-no_content-model; this example showsno-contentand 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
📒 Files selected for processing (12)
CHANGELOG.mddocs/DOCS_SITE_ROADMAP.mddocs/LANGUAGE.mddocs/ROADMAP.mddocs/SPECIFICATION.mddocs/proposals/0008-language-reference-export.mddocs/proposals/README.mdtests/test_reference.pytranson/reference.pytranson/resources/LANGUAGE.mdtranson/rules.pytranson/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>
|
Addressed the CodeRabbit review in 830acfb. Disposition of all 10 findings: Fixed (7):
Declined (3), with reasons:
397 tests pass; |
There was a problem hiding this comment.
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 winSkip
NO_CONTENTbefore enforcing the list shape.The docstring promises that
NO_CONTENTresults are skipped, but the new guard rejects the sentinel because it is not a list. A conditionalitemstemplate can therefore abort the entire map instead of omitting the current element. Checkitems is t.NO_CONTENTfirst, 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_CONTENTinputs 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 winCover 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
📒 Files selected for processing (10)
CHANGELOG.mddocs/SPECIFICATION.mddocs/proposals/0008-language-reference-export.mddocs/proposals/README.mdtests/test_copy_output.pytests/test_invalid_value.pytests/test_reference.pytranson/reference.pytranson/rules.pytranson/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
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>
There was a problem hiding this comment.
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 winApply
copy_outputto mutableno_contentsubstitutions.
no_contentis caller-supplied and may bedataitself or a mutable subobject. Returning it unchanged withcopy_output=Truecan therefore preserve aliases to the input, violating the documented copy boundary. Keep the rawNO_CONTENTidentity exception, but deep-copy other substitutions when requested.As per path instructions,
copy_output=Truemust 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
📒 Files selected for processing (3)
CHANGELOG.mdtests/test_copy_output.pytranson/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>
There was a problem hiding this comment.
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 liftMove this to an installed-artifact test.
get_language_reference()andpackagedboth readtranson/resources/LANGUAGE.mdfrom 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
📒 Files selected for processing (8)
CHANGELOG.mddocs/DOCS_SITE_ROADMAP.mddocs/LANGUAGE.mddocs/ROADMAP.mddocs/SPECIFICATION.mddocs/proposals/0008-language-reference-export.mdtests/test_reference.pytranson/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>
There was a problem hiding this comment.
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 winSpecify 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 winDescribe
ziprows as lists, not tuples.
§4.4andtranson/rules.pystate thatzipreturns 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
📒 Files selected for processing (4)
CHANGELOG.mddocs/ROADMAP.mddocs/SPECIFICATION.mddocs/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
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>
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), theNO_CONTENTmodel, the error taxonomy,expr/callmachinery, 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,Contextcopy-on-write invariants,NoContentimplementation, error-plumbing contract); §4 collapsed to a pointer plus the retained Recursion budget invariant; §11 points at the reference's worked example; §5 now namesLANGUAGE.mdas the one hand-written artifact and documents the new export as §5.2.transon/rules.pydocstrings (they grow richer): accessor out-of-scope errors,attr'sNO_CONTENT-vs-TransformationErrorsplit, fullmap/filtermode semantics,zip/join/file/formatedge cases,expr/callempty-valueserrors — plus the one sanctioned docstring→reference pointer for the sharedexpr/callapplication semantics. Thesetdocstring trades its deep scoping model (now reference-owned) for a compact per-rule statement.Transformerclass docstring slimmed ~225 → ~75 lines: embedder-only (usage, constructor options, error catching, extending). The pitch/install/comparison content is owned solely byREADME.md(already there — no README change needed).R-35 — packaging.
transon/resources/LANGUAGE.mdships in the wheel and sdist (hatchling picks it up with zero config change — verified by building and inspecting both).docs/LANGUAGE.mdstays 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}withREFERENCE_VERSION '1.0', fence-aware deterministic##-heading splitting, GitHub-style slug ids with collision suffixes, the preamble rule, and apython -m transon.referenceCLI. Engine-global (baseTransformeronly); language facts only.Reviewer notes
get_all_docs()['doc']shrinks to the embedder narrative; per-rule doc text inget_all_docs()andget_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).tests/test_reference.py(not catalog-coverage — the RFC deliberately dropped that): editingLANGUAGE.md's section set requires touching the pin and following thereference_versionpolicy. Also tested: sections-concatenation parity, packaging parity viaimportlib.resources, canonical↔packaged identity, splitter edge cases (no preamble, slug collisions, fenced##, deeper headings).pytest392 passed, 99 % coverage (not reduced);python -m transon.docsreports noTBD;scripts/check_roadmap.pyconsistent; wheel + sdist built and inspected.[Unreleased]; R-34/35/36 →donewith Shipped notes; RFC 0008 + proposals index → Implemented (unreleased). Cross-repo follow-ups (out of scope here): D-20 docs-site migration,transon-authoringreference pin.🤖 Generated with Claude Code
Summary by CodeRabbit
get_language_reference()for offline access to the Language Reference (versioned, deterministic section splitting) plus a CLI to output it as JSON.map“items” mode now raises a located definition error whenitemsdoesn’t evaluate to a list.transform(..., copy_output=True)preservesNO_CONTENTidentity, including when nested in copied outputs.NO_CONTENTidentity/validation behavior.