feat(doc-ir): the dual-render vertical slice — resolve (rail walk) + ogar-render-typst#222
Merged
Merged
Conversation
…ogar-render-typst, one document → two projections The composition brick gains its missing verb and its second surface: - ogar-doc-ir::resolve (feature classview): resolve_doc/resolve_slot — each ObjectSlot resolves through lance-graph-contract's selection rail walk (named view governs the root, nested hops resolve per-class via the DocObjectSource dependency inversion; consumer owns graph/values/bindings). Missing target → explicit snapshot fallback (hex sha256) or Unresolvable — never silence. 4 new unit tests. - ogar-render-typst (NEW crate): Typst SOURCE emitter over the same FieldView rows the askama surface renders — the paged/@revision projection. Escaping proven; deliberately NO typst compiler dep (.typ→PDF is consumer egress). 4 unit tests. - tests/dual_render.rs — THE PROOF, output inspected: one DocCompose (User + WorkPackage + Attachment + a tesseract-rs doc.v1 invoice slot + a deleted target) resolved once, rendered through askama HTML AND Typst source with identical facts: the assignee rail hop lands at depth 1 in both; user.inline masks email/role out of both; the retina's unread ust is absent from both (cleared presence bit, via project::field_mask/masked_values — the observation is just a graph node); the deleted slot shows its sha256 fallback in both. 2 E2E tests. - Contract deps FLOAT on the lance-graph #776 branch (selection module); flip back to main on merge — commented at every site. - DISCOVERY-MAP: D-DOCIR-DUAL-RENDER appended [G]. Gates: ogar-doc-ir 26/26 (classview), ogar-render-typst 6/6, clippy -D warnings clean on both, fmt clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HCghCf6rxf2wcqi2cor6RD
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_c3807831-53e6-4a8c-b18b-348c9868fdc9) |
AdaWorldAPI
marked this pull request as ready for review
July 21, 2026 05:56
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 462e127f51
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…st marker escaping Review fixes on #222: - resolve_slot now verifies the slot's named view projects the ROOT's own class before walking. A stale or cross-class view name previously produced a silently-EMPTY Resolved (the walker prunes the foreign mask fail-closed); it now takes the fallback/unresolvable arm so the outcome says what actually happened. (codex P2) - escape_typst escapes the Typst BLOCK markers '=', '-', '+' in line-start position (start of string or after a newline), so user data cannot become a heading/list/enum in the emitted page; mid-line they stay inert and unescaped. (codex P2) - Pinned lance-graph-contract rev refreshed to 241c7ef (picks up the walker's path-local cycle guard + view/class agreement + depth ceiling from lance-graph #776). Falsifier tests: cross-class root view → Unresolvable and → Fallback when a snapshot is attached; line-start markers escaped at string start, after embedded newlines, and inside field-view values, while mid-line occurrences stay untouched.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What — the document IR slice, closed
The composition brick (
DocNode/ObjectSlot, #219) gains its missing verb and its second surface. One composed document is resolved once and rendered through two genuinely different projections from the same rows — the renderer-independence proof the DocIr architecture demanded.ogar-doc-ir::resolve(featureclassview)resolve_doc/resolve_slot: everyObjectSlotresolves through the contract's rail walk (lance_graph_contract::selection::walk_rails) — the slot's named view governs its root; nested hops resolve per-class. No query document anywhere: nesting = masks × the walk.DocObjectSource— dependency inversion, house shape: the consumer owns the graph (RailGraph), the values, and the view bindings; the resolver owns only the procedure.Unresolvable— never silence (the ActionText missing-object path, mechanized).ogar-render-typst(new crate)Typst source emitter over the same
FieldViewrows the askama surface renders — the paged/@revisionprojection (ResolutionModepairing: living screen ↔Live, page ↔Revision/Snapshot). Markup escaping proven. Deliberately no typst compiler dependency —.typ→PDF is consumer egress.The proof (
tests/dual_render.rs, output inspected)One
DocCompose— User + WorkPackage + Attachment slots, a tesseract-rsdoc.v1invoice as an ObjectSlot (the retina participates as a plain graph node whose presence/values areproject::{field_mask, masked_values}— same walk as live objects), plus a deleted target — rendered to both surfaces:netto+IBAN);name (nested) → Alice Muster);user.inlinemasks email/role out of both;ustis absent from both (cleared presence bit — C2, no sentinel);Sample of the inspected Typst output:
Float note
Contract deps FLOAT on the lance-graph #776 branch (the
selectionmodule); flip back tomainon its merge — commented at every dep site (ogar-class-view,ogar-doc-ir,ogar-from-ruff,ogar-render-askama,ogar-render-typst). Merge order: lance-graph #776 first, then flip, then this.Verification (Rust 1.95)
cargo test -p ogar-doc-ir --features classview→ 26/26.cargo test -p ogar-render-typst→ 6/6 (4 emitter + 2 E2E).-D warningsclean on both; fmt clean.--nocapture), snippet above.Board
DISCOVERY-MAP:
D-DOCIR-DUAL-RENDERappended[G](built + inspected), deferred items named (DocOp, Lance-versionedRevision(n)lookup,FieldViewenum widening).🤖 Generated with Claude Code
Generated by Claude Code