Add observability for inline wrapping token classification (#296) - #303
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Observability Infrastructure for Inline-Wrapping Token ClassificationImplements structured observability for the inline-wrapping token- and fragment-classification pipeline to address issue Key Changes
Design Decisions
Follow-up Work
WalkthroughIntroduce structured tracing across inline-wrap token classification: add tracing deps and docs; instrument parsing, fragment classification and predicate helpers; add compile- and runtime tests asserting emitted logs and attribute acceptance. ChangesInline-wrap token classification observability
Sequence Diagram(s)sequenceDiagram
participant Tokeniser
participant parse_link_or_image
participant find_footnote_end
participant InlineFragment
participant trace_text_snippet
participant Logging
Tokeniser->>parse_link_or_image: attempt parse link/image or footnote
parse_link_or_image->>find_footnote_end: delegate footnote label scan
find_footnote_end->>Logging: emit prefix_mismatch / label recognised / unterminated_bracket
parse_link_or_image->>Logging: emit footnote reference parsed / link or image parsed (token, is_image)
InlineFragment->>trace_text_snippet: request UTF-8 snippet (80 bytes)
trace_text_snippet-->>InlineFragment: return preview + truncated flag
InlineFragment->>Logging: emit "fragment classified" debug event (token, truncated, kind)
Possibly related issues
Possibly related PRs
Poem
Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (1 error, 3 warnings)
✅ Passed checks (16 passed)
📋 Issue PlannerBuilt with CodeRabbit's Coding Plans for faster development and fewer bugs. View plan used: ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Reviewer's GuideAdds Sequence diagram for link and footnote parsing with tracingsequenceDiagram
participant Wrapper
participant parse_link_or_image
participant find_footnote_end
participant tracing
Wrapper->>parse_link_or_image: parse_link_or_image(text, idx)
parse_link_or_image->>find_footnote_end: find_footnote_end(text, idx)
alt footnote_prefix_mismatch_or_unterminated
find_footnote_end->>tracing: trace!(reason = prefix_mismatch or unterminated_bracket)
find_footnote_end-->>parse_link_or_image: None
else footnote_label_span_recognised
find_footnote_end->>tracing: trace!(token, start, end)
find_footnote_end-->>parse_link_or_image: Some(text_end)
parse_link_or_image->>tracing: debug!(token) %% footnote reference parsed
end
alt link_or_image_with_url
parse_link_or_image->>tracing: trace!(token, is_image)
else no_url_or_unbalanced
parse_link_or_image-->>Wrapper: (token, next_idx)
end
parse_link_or_image-->>Wrapper: (token, next_idx)
Flow diagram for fragment classification with structured tracingflowchart TD
A[Input text] --> B{is_whitespace_token}
B -- yes --> K[FragmentKind::Whitespace]
B -- no --> C[trim_end_matches is_trailing_punct]
C --> D[trim_start_matches is_opening_punct]
D --> E{is_inline_code_token on variants}
E -- yes --> L[FragmentKind::InlineCode]
E -- no --> F{fragment_is_link}
F -- yes --> M[FragmentKind::Link]
F -- no --> G{looks_like_footnote_ref or ends_with_footnote_ref}
G -- yes --> N[FragmentKind::FootnoteRef]
G -- no --> O[FragmentKind::Plain]
K --> P[debug! fragment classified]
L --> P
M --> P
N --> P
O --> P
P --> Q[Output FragmentKind]
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
9766055 to
3413ce3
Compare
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
echo "=== tests/ui/tracing_instrument_pass.rs ==="
cat tests/ui/tracing_instrument_pass.rs
echo ""
echo "=== tests/compile.rs ==="
cat tests/compile.rs
echo ""
echo "=== src/wrap/inline/fragment.rs - test block ==="
awk '/^#\[cfg\(test\)\]/,0' src/wrap/inline/fragment.rs
echo ""
echo "=== src/wrap/inline/predicates.rs - full content ==="
cat src/wrap/inline/predicates.rs
echo ""
echo "=== logs_contain assertions in fragment.rs ==="
rg -n "logs_contain\|assert!" --type=rust src/wrap/inline/fragment.rs
echo ""
echo "=== logs_contain assertions in predicates.rs ==="
rg -n "logs_contain\|assert!" --type=rust src/wrap/inline/predicates.rs
echo ""
echo "=== traced_test usage ==="
rg -rn "traced_test" --type=rust -A3 -B2Length of output: 13850
✅ All checks resolved
The proptest in The sole remaining deferred item is |
|
@coderabbitai Have the following failed checks now been resolved? If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures. Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already. ❌ Failed checks (1 error, 2 warnings)
|
This comment was marked as resolved.
This comment was marked as resolved.
|
@coderabbitai Have the following failed checks now been resolved? If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures. Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already. ❌ Failed checks (1 error, 2 warnings)
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
echo "=== src/wrap/inline/fragment.rs - full test block ==="
awk '/^#\[cfg\(test\)\]/,0' src/wrap/inline/fragment.rs
echo ""
echo "=== FragmentKind variants ==="
rg -n "enum FragmentKind" --type=rust -A10 src/wrap/inline/fragment.rs
echo ""
echo "=== InlineFragment struct ==="
rg -n "struct InlineFragment\|pub kind\|pub fn kind\| kind:" --type=rust -A5 src/wrap/inline/fragment.rs
echo ""
echo "=== logs_contain assertions in fragment.rs ==="
rg -n "logs_contain\|assert!\|traced_test" --type=rust src/wrap/inline/fragment.rs
echo ""
echo "=== insta usage ==="
rg -rn "insta\|assert_snapshot" --type=rust
rg -n "insta" Cargo.toml
echo ""
echo "=== open issues ==="
gh issue list --repo leynos/mdtablefix --state open --limit 50Length of output: 5551
✅ All checks resolved
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@src/wrap/inline/fragment.rs`:
- Around line 218-266: Replace the five near-identical tests
fragment_classification_logs_footnote_ref,
fragment_classification_logs_inline_code, fragment_classification_logs_link,
fragment_classification_logs_whitespace, and fragment_classification_logs_plain
with a single #[traced_test] parameterised test using rstest that iterates input
strings and their expected kinds (e.g. ("[^1]", "FootnoteRef"), ("`code`",
"InlineCode"), ("[text](...)", "Link"), (" ", "Whitespace"), ("plain",
"Plain")) and asserts the same log fragments ("fragment classified",
"kind={expected}", "token=", "truncated=") after creating
InlineFragment::new(input.to_string()); keep the existing
fragment_classification_does_not_require_subscriber test separate; add use
rstest::rstest; to the tracing_tests imports so rstest is available.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: 21bda48d-40f0-49bb-9870-e7c9a900671c
📒 Files selected for processing (1)
src/wrap/inline/fragment.rs
|
Actionable comments posted: 0 |
|
@coderabbitai Have the following now been resolved? Annul any requirements that violate the en-GB-oxendict spelling (-ize / -yse / -our) conventions (for example a request to replace "normalize" with "normalise" or "artefact" with "artifact"), or where the requirement unnecessarily increases cyclomatic complexity. |
|
@coderabbitai please create a new GitHub issue for the following: Domain Architecture |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: gh issue create \
--repo leynos/mdtablefix \
--title "Isolate vendor-specific tracing from domain logic behind adapter boundaries" \
--assignee leynos \
--body "## Background
Raised during review of PR `#303` by `@leynos`.
Domain functions in \`src/wrap/inline/\` and \`src/wrap/tokenize/\` currently import and use the vendor-specific \`tracing\` framework directly (\`#[tracing::instrument]\`, \`debug!\`, \`trace!\`, \`tracing::enabled!\`). This couples infrastructure concerns to domain logic, making the domain harder to test without a tracing subscriber and harder to migrate to a different observability backend in the future.
## Required work
1. Define domain-level event types — e.g. \`enum ClassificationEvent\` — that capture the observable outcomes of classification and parsing decisions without referencing any external crate.
2. Refactor classification functions (\`classify_fragment_kind\`, \`parse_link_or_image\`, \`find_footnote_end\`, the footnote predicate helpers) to accept an optional observer (e.g. a callback or a trait object implementing an \`Observer\` trait) and emit domain events through it, rather than emitting tracing calls inline.
3. Implement a \`tracing\`-backed adapter that translates \`ClassificationEvent\` values into the appropriate \`debug!\`/\`trace!\` calls. Wire this adapter at the library boundary so existing instrumented behaviour is preserved.
4. Remove direct \`tracing\` imports from all domain modules; retain the dependency only in the adapter layer and in \`[dev-dependencies]\` for tests.
## Acceptance criteria
- No \`use tracing::\` import appears inside domain modules (\`src/wrap/inline/\`, \`src/wrap/tokenize/\`).
- Domain functions can be called without any tracing subscriber installed and without any \`enabled!\` guard (all guards move to the adapter).
- Existing traced-event tests continue to pass via the adapter.
- Linters and tests pass under \`make test\`.
## References
- PR `#303`
- Issue `#296`
"Length of output: 2075
|
Summary
Closes #296
This branch brings the inline-wrapping token- and fragment-classification
pipeline into compliance with the project observability policy introduced
for GFM footnote-reference handling in #280.
tracingcrate and derivesDebugonSpanKindsoclassification outcomes appear as structured fields.
debug!at high-value decision points (footnote parse, fragmentclassification, span promotion) and
trace!at branch-level checks,using consistent field names (
token,kind,start,end,width).metricscounters until a clear per-wrap use caseemerges; instrumentation remains purely additive with no global
subscriber or recorder installation.
Test plan
make check-fmtmake lintmake testcoderabbit review --agent) — 0 findingsMade with Cursor
Summary by Sourcery
Add structured tracing around inline wrapping tokenization and classification to improve observability without changing wrapping behavior.
Enhancements:
Build: