commits
3dac9f7d Merge commit 'b2b6f8127c880f184ba686ee2ec37d4fdcc31dab'
9706a259 doc fixes mainly
483c869b fix(odoc): add missing dependency base64
de593b37 Add missing dependency: base64
2cb07b81 fix(odoc): strip inline include decls to reduce memory usage 5.7x
git-subtree-dir: odoc
git-subtree-split: 3dac9f7dd6ec9779d389b7731ec2a64b63b4e44a
71fe7ccd3 Merge branch 'point-release-fixes' of https://github.com/jonludlam/odoc
4d53f50da Make all warnings respect --warn-error
d1f796f14 Add test showing --warn-error doesn't affect unresolved references
d6c8ece57 Don't resolve imports without digests during compile
18adbf89b Add test for no-alias-deps import resolution bug
c3f0f46ee Update for dune 3.21
git-subtree-dir: odoc
git-subtree-split: 71fe7ccd36eee7f244a355653e10de197d6bcb94
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests addMarker, clearMarkers, addImageOverlay, removeImageOverlay
commands in a standalone HTML page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New commands:
- enableBboxDraw: custom rectangle drawing with bbox_drawn event
- addImageOverlay/removeImageOverlay: display data URL images on map
- addMarker/clearMarkers: circle markers with labels
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests PNG encoding and data URL generation in a web worker.
Verified: 4x4 RGBA image encodes to valid PNG, renders as <img>.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests run in a web worker (sync XHR requires worker context).
Fetches a real scales.npy from dl2.geotessera.org, parses it,
and verifies the shape and data values.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Widen sidebar from 200px to 260px with updated max-width calculations
- Collapse top two wrapper levels so content aligns with header
- Add border-left indentation guides on nested lists
- Replace original toggle arrows with larger inline chevrons (1em, rotate on expand)
- Separate click targets: chevrons toggle expand/collapse, links navigate
- Align childless items with toggle items via 20px margin-left
- Fix CSS cascade where .jon-shell-main ul overrode sidebar ul padding
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add browser test that compiles OCaml to JS via js_of_ocaml and verifies
fetch, npy parsing, and mosaic assembly work in a real browser.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of requiring every .mld file to specify @x-ocaml.universe and
@x-ocaml.worker tags individually, configure the default universe path
once in dune-workspace (--config x-ocaml.universe=/_opam). The shell
emits <meta> tags from config values, and per-page @x-ocaml tags can
still override them.
Changes:
- dune-workspace: add --config x-ocaml.universe=/_opam to html_flags
- gen_rules.ml: pass --config to odoc html-generate for @site build
- odoc_jon_shell.ml: emit <meta> tags from x-ocaml.* config values
- odoc generator.ml: pass config to shell page_creator
- interactive_extension.ml: upsert meta tags (update existing or create)
- x_ocaml.ml: infer jtw backend from x-ocaml-universe meta tag
- Remove @x-ocaml.universe/@x-ocaml.worker from 14 .mld files using
the default /_opam universe
- deploy-site.sh: add dune install x-ocaml, chmod fix, widget-leaflet
- findlibish.ml: module detection fallback via jsoo runtime
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generate tessera-viz.opam from dune-project. All odoc documentation
is in the .mli with section headers and docstrings for every public
type and function.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add color_of_hex for parsing hex color strings and classification_to_rgba
for mapping integer class predictions to colored RGBA pixels. Unknown
classes render as black. Add unit arg to resolve optional alpha parameter.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Convert 3-component PCA matrix to false-color RGBA image with
per-component percentile clipping and 0-255 scaling. Optional args
moved before positional to satisfy OCaml's optional-arg resolution.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add the tessera-viz library skeleton with dune-project, .mli interface,
and a working percentile function with linear interpolation. Other API
functions are stubbed with failwith for TDD iteration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generate opam file from dune-project. All 15 tests pass across grid
math, dequantization, mosaic, and fetch_mosaic_sync.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add end-to-end test for fetch_mosaic_sync using mock fetch function
with numpy fixture files. Verifies the full pipeline: bbox -> tile
enumeration -> fetch -> dequantize -> mosaic -> correct output values.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add mosaic tests verifying horizontal and vertical tile assembly.
North tiles appear at top (row 0), south at bottom. Confirms correct
grid position calculation and data placement.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add dequantization test with numpy fixtures (2x3x4 int8 embeddings,
2x3 float32 scales). Verifies correct int8 * scale multiplication
and output matrix dimensions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add new tessera-geotessera library with dune project structure, public
API (.mli), and grid math implementation (snap_to_grid, tiles_for_bbox,
tile_name, URL construction). Includes full implementations of
dequantize, mosaic, and fetch_mosaic_sync. Grid math tests all pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add trailing-comma (1D shape) and scalar shape edge case tests
- Comprehensive .mli documentation with usage example
- Auto-generated opam file
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each foundations lecture now specifies @x-ocaml.universe and
@x-ocaml.worker so interactive code cells use the correct opam
package set.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Site pages (blog, notebooks) don't need the reference sidebar — it's only
for @doc output. Also adds the opam universe build step to deploy-site.sh,
copies odoc.support into the site tree, and refreshes the homepage with
recent entries and an about section.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Switch from server-rendered sidebar to JS-rendered sidebar from
sidebar_data JSON (same approach as odoc-docsite). On link clicks
within /reference/, fetch the page, swap .odoc-content, update title
and body class — no full reload. Back/forward via popstate.
- New odoc_jon_shell_js.ml: sidebar rendering, collapsible entries,
SPA navigation with click interception and resource deduplication
- odoc_jon_shell.ml: inject BASE_URL/CURRENT_URL/sidebar JSON in head,
register JS support file, empty sidebar container filled by JS,
extension resources moved to head for SPA discovery
- odoc_jon_shell_css.ml: collapsible toggle triangles, sidebar-label
styling for non-link entries
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add sidebar pipeline: compile-index → sidebar-generate → html-generate --sidebar
- jon-shell: render sidebar nav with sticky CSS layout
- Convert all {@ocamltop blocks to {@ocaml for interactive extension
- odoc-interactive-extension: handle autorun (→ run-on=load) and skip tags
- Remove package prefix from URLs (parent-id uses "." for root pages)
- Add projects/index.mld placeholder, @children_order for notebooks
- Add (prefix reference) to dune-workspace for @doc output
- Update deploy-site.sh for two-pass build (site + reference docs)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the (documentation ...) stanza in site/dune with explicit
odoc compile → link → html-generate rules generated by a small OCaml
tool (site-builder/gen_rules.exe).
The generator walks site/ finding .mld files and static assets, then
emits two directory-target rules (compile+link → _odoc/, html-generate
+ support-files + assets → _html/) and a top-level @site alias.
Build the site with: dune build @site
Output lands in: _build/default/site/_html/
The committed site/dune.inc is kept in sync via dune build @runtest
(diff check against the generated output).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests the full end-to-end flow of runtime preloaded package detection:
- Preloaded package (yojson): succeeds without fetching .cma.js
- Normal package (stringext): fetches and loads from universe
- CRC mismatch (crc_conflict): raises Crc_mismatch with bogus CRC
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Captures the theming pattern, available infrastructure (--config,
theme CSS files, dune-workspace html_flags), and the helper code
prototyped during this branch.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The scrollycode theme support (scrollycode_theme_links helper and
--config scrollycode.theme=warm in dune-workspace) belongs in a
dedicated scrollycode shell, not in the generic docsite shell.
The generic --config infrastructure (config_values on Config.t and
the --config CLI arg) is retained for use by any shell.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These are promoted by dune's (promote (until-clean)) but should not
be tracked in the monorepo.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a config_values field to Html.Config.t and a --config KEY=VALUE
repeatable CLI argument to odoc html-generate, allowing arbitrary
configuration to flow from the command line through to shell plugins.
The docsite shell reads scrollycode.theme from config_values and emits
a <link> for the corresponding theme CSS in both page_creator and
src_page_creator. The dune-workspace passes --config
scrollycode.theme=warm via html_flags.
SPA navigation now collects head script:not([src]) elements from
fetched pages and executes them after newly added external scripts
have loaded. Inline scripts are stamped with a data-spa-inline
attribute (content hash) at HTML generation time; the SPA checks this
attribute to avoid re-executing scripts already present in <head>.
Document the resource type's SPA execution semantics in both
odoc_extension_registry.ml and odoc_extension_api.ml, covering
deduplication behaviour, execution timing, and guidance for extension
authors (prefer MutationObserver over re-execution, avoid
DOMContentLoaded in inline scripts).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add symtable_memo and crc_memo hash tables to Impl for caching
module availability and CRC lookups (both binary and server side)
- Extract pure check_preload_status function into Impl for testability
- Capture server-side CRCs from fetched .cmi files in add_dynamic_cmis_sync
- Raise Crc_mismatch exception (instead of returning false) when a
preloaded package has different CRCs than the universe
- Add 8 ppx_expect tests covering: match, mismatch, partial load,
empty, missing CRCs, server CRC priority, single mismatch in group
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bake module CRCs into dynamic_cmis.json when building universes, then
verify at require-time that preloaded modules match the universe version.
Three defensive checks:
- All modules loaded: package is preloaded (skip import)
- No modules loaded: package is not preloaded (import normally)
- Partial: warn and import (something is wrong)
- CRC mismatch: warn and import (version skew between binary and universe)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The map demo requires this widget package at runtime.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use relativize_or_fallback for META files (already used for CMI files),
fixing a None exception when libraries are installed outside the
standard findlib tree.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use Symtable.Global.of_ident / is_global_defined to detect packages
already linked into the worker binary at runtime, eliminating the
hand-maintained list that drifts out of sync with example/dune deps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When mode_links is configured, mode names (local, portable, etc.)
and jkind names (value_or_null, float64, etc.) are rendered as
hyperlinks to URI#name. The @ and @@ keywords remain unlinked.
Implementation approach:
- Add O.mode tag in document layer (codefmt.ml) to mark mode/jkind
names with a "mode" source tag
- Update all mode rendering sites in generator.ml: arrow arg/ret
modes, Poly jkind quantifiers, type param jkinds, and value
modalities
- In HTML renderer, detect "mode" tags and emit <a> with
class="mode-link" when mode_links config is set, otherwise
render as <span class="mode">
- Refactor format_params to return Codefmt.t instead of string
to support tagged jkind names in type parameters
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Passes a base URI to the HTML renderer for linking mode and jkind
names to external documentation. Fragment is the name as rendered.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Optional base URI for linking mode and jkind names to external
documentation. When set, mode names become fragments appended to
the URI, e.g. 'local' links to URI#local.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix two bugs in the cmti (typedtree) loader path that were already
fixed in the cmi (Types) loader:
1. Extract jkind annotations from Ttyp_poly binding sites instead of
discarding them. Previously the OxCaml Ttyp_poly handler had
`(fun (s, _) -> (s, None))` which dropped the jkind annotation.
Now extracts Pjk_abbreviation names, matching the cmi path.
2. Suppress return modes on inner arrow types. When the return type
of an arrow is itself an arrow, the return mode is always implied
(a closure capturing a local value is necessarily local). This
matches the elision logic in cmi.cppo.ml and Printtyp.
Add integration test case with Poly quantifier carrying value_or_null
jkind. Update expected output: jkind at binding site only, return
mode elision on inner arrows, @ keyword count updated from 8 to 12.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3dac9f7d Merge commit 'b2b6f8127c880f184ba686ee2ec37d4fdcc31dab'
9706a259 doc fixes mainly
483c869b fix(odoc): add missing dependency base64
de593b37 Add missing dependency: base64
2cb07b81 fix(odoc): strip inline include decls to reduce memory usage 5.7x
git-subtree-dir: odoc
git-subtree-split: 3dac9f7dd6ec9779d389b7731ec2a64b63b4e44a
71fe7ccd3 Merge branch 'point-release-fixes' of https://github.com/jonludlam/odoc
4d53f50da Make all warnings respect --warn-error
d1f796f14 Add test showing --warn-error doesn't affect unresolved references
d6c8ece57 Don't resolve imports without digests during compile
18adbf89b Add test for no-alias-deps import resolution bug
c3f0f46ee Update for dune 3.21
git-subtree-dir: odoc
git-subtree-split: 71fe7ccd36eee7f244a355653e10de197d6bcb94
- Widen sidebar from 200px to 260px with updated max-width calculations
- Collapse top two wrapper levels so content aligns with header
- Add border-left indentation guides on nested lists
- Replace original toggle arrows with larger inline chevrons (1em, rotate on expand)
- Separate click targets: chevrons toggle expand/collapse, links navigate
- Align childless items with toggle items via 20px margin-left
- Fix CSS cascade where .jon-shell-main ul overrode sidebar ul padding
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of requiring every .mld file to specify @x-ocaml.universe and
@x-ocaml.worker tags individually, configure the default universe path
once in dune-workspace (--config x-ocaml.universe=/_opam). The shell
emits <meta> tags from config values, and per-page @x-ocaml tags can
still override them.
Changes:
- dune-workspace: add --config x-ocaml.universe=/_opam to html_flags
- gen_rules.ml: pass --config to odoc html-generate for @site build
- odoc_jon_shell.ml: emit <meta> tags from x-ocaml.* config values
- odoc generator.ml: pass config to shell page_creator
- interactive_extension.ml: upsert meta tags (update existing or create)
- x_ocaml.ml: infer jtw backend from x-ocaml-universe meta tag
- Remove @x-ocaml.universe/@x-ocaml.worker from 14 .mld files using
the default /_opam universe
- deploy-site.sh: add dune install x-ocaml, chmod fix, widget-leaflet
- findlibish.ml: module detection fallback via jsoo runtime
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add new tessera-geotessera library with dune project structure, public
API (.mli), and grid math implementation (snap_to_grid, tiles_for_bbox,
tile_name, URL construction). Includes full implementations of
dequantize, mosaic, and fetch_mosaic_sync. Grid math tests all pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Site pages (blog, notebooks) don't need the reference sidebar — it's only
for @doc output. Also adds the opam universe build step to deploy-site.sh,
copies odoc.support into the site tree, and refreshes the homepage with
recent entries and an about section.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Switch from server-rendered sidebar to JS-rendered sidebar from
sidebar_data JSON (same approach as odoc-docsite). On link clicks
within /reference/, fetch the page, swap .odoc-content, update title
and body class — no full reload. Back/forward via popstate.
- New odoc_jon_shell_js.ml: sidebar rendering, collapsible entries,
SPA navigation with click interception and resource deduplication
- odoc_jon_shell.ml: inject BASE_URL/CURRENT_URL/sidebar JSON in head,
register JS support file, empty sidebar container filled by JS,
extension resources moved to head for SPA discovery
- odoc_jon_shell_css.ml: collapsible toggle triangles, sidebar-label
styling for non-link entries
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add sidebar pipeline: compile-index → sidebar-generate → html-generate --sidebar
- jon-shell: render sidebar nav with sticky CSS layout
- Convert all {@ocamltop blocks to {@ocaml for interactive extension
- odoc-interactive-extension: handle autorun (→ run-on=load) and skip tags
- Remove package prefix from URLs (parent-id uses "." for root pages)
- Add projects/index.mld placeholder, @children_order for notebooks
- Add (prefix reference) to dune-workspace for @doc output
- Update deploy-site.sh for two-pass build (site + reference docs)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the (documentation ...) stanza in site/dune with explicit
odoc compile → link → html-generate rules generated by a small OCaml
tool (site-builder/gen_rules.exe).
The generator walks site/ finding .mld files and static assets, then
emits two directory-target rules (compile+link → _odoc/, html-generate
+ support-files + assets → _html/) and a top-level @site alias.
Build the site with: dune build @site
Output lands in: _build/default/site/_html/
The committed site/dune.inc is kept in sync via dune build @runtest
(diff check against the generated output).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests the full end-to-end flow of runtime preloaded package detection:
- Preloaded package (yojson): succeeds without fetching .cma.js
- Normal package (stringext): fetches and loads from universe
- CRC mismatch (crc_conflict): raises Crc_mismatch with bogus CRC
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The scrollycode theme support (scrollycode_theme_links helper and
--config scrollycode.theme=warm in dune-workspace) belongs in a
dedicated scrollycode shell, not in the generic docsite shell.
The generic --config infrastructure (config_values on Config.t and
the --config CLI arg) is retained for use by any shell.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a config_values field to Html.Config.t and a --config KEY=VALUE
repeatable CLI argument to odoc html-generate, allowing arbitrary
configuration to flow from the command line through to shell plugins.
The docsite shell reads scrollycode.theme from config_values and emits
a <link> for the corresponding theme CSS in both page_creator and
src_page_creator. The dune-workspace passes --config
scrollycode.theme=warm via html_flags.
SPA navigation now collects head script:not([src]) elements from
fetched pages and executes them after newly added external scripts
have loaded. Inline scripts are stamped with a data-spa-inline
attribute (content hash) at HTML generation time; the SPA checks this
attribute to avoid re-executing scripts already present in <head>.
Document the resource type's SPA execution semantics in both
odoc_extension_registry.ml and odoc_extension_api.ml, covering
deduplication behaviour, execution timing, and guidance for extension
authors (prefer MutationObserver over re-execution, avoid
DOMContentLoaded in inline scripts).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add symtable_memo and crc_memo hash tables to Impl for caching
module availability and CRC lookups (both binary and server side)
- Extract pure check_preload_status function into Impl for testability
- Capture server-side CRCs from fetched .cmi files in add_dynamic_cmis_sync
- Raise Crc_mismatch exception (instead of returning false) when a
preloaded package has different CRCs than the universe
- Add 8 ppx_expect tests covering: match, mismatch, partial load,
empty, missing CRCs, server CRC priority, single mismatch in group
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bake module CRCs into dynamic_cmis.json when building universes, then
verify at require-time that preloaded modules match the universe version.
Three defensive checks:
- All modules loaded: package is preloaded (skip import)
- No modules loaded: package is not preloaded (import normally)
- Partial: warn and import (something is wrong)
- CRC mismatch: warn and import (version skew between binary and universe)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When mode_links is configured, mode names (local, portable, etc.)
and jkind names (value_or_null, float64, etc.) are rendered as
hyperlinks to URI#name. The @ and @@ keywords remain unlinked.
Implementation approach:
- Add O.mode tag in document layer (codefmt.ml) to mark mode/jkind
names with a "mode" source tag
- Update all mode rendering sites in generator.ml: arrow arg/ret
modes, Poly jkind quantifiers, type param jkinds, and value
modalities
- In HTML renderer, detect "mode" tags and emit <a> with
class="mode-link" when mode_links config is set, otherwise
render as <span class="mode">
- Refactor format_params to return Codefmt.t instead of string
to support tagged jkind names in type parameters
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix two bugs in the cmti (typedtree) loader path that were already
fixed in the cmi (Types) loader:
1. Extract jkind annotations from Ttyp_poly binding sites instead of
discarding them. Previously the OxCaml Ttyp_poly handler had
`(fun (s, _) -> (s, None))` which dropped the jkind annotation.
Now extracts Pjk_abbreviation names, matching the cmi path.
2. Suppress return modes on inner arrow types. When the return type
of an arrow is itself an arrow, the return mode is always implied
(a closure capturing a local value is necessarily local). This
matches the elision logic in cmi.cppo.ml and Printtyp.
Add integration test case with Poly quantifier carrying value_or_null
jkind. Update expected output: jkind at binding site only, return
mode elision on inner arrows, @ keyword count updated from 8 to 12.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>