Skip to content

research

Caleb Buxton edited this page Jul 2, 2026 · 2 revisions

Research — Issue #1: Ship duckling gem (time extraction via Magnus + Duckling (Rust))

Breadth-first summary of all research topics. Each subtopic is a self-contained terrain map: observable facts, verified file paths, exact versions, and code references. No prescriptive recommendations — those live in the roadmap.

Table of Contents

  • Duckling (Rust) API Surface — Complete public Rust API surface: parse functions, all types (Entity/DimensionValue/TimeValue/TimePoint/Grain), Naive vs Instant time semantics, and the 49-language locale system.
  • Build Wiring Research — How to wire the Magnus + rb-sys native extension: cdylib extension crate layout, extconf.rb pattern, Rakefile ExtensionTask, and CI Rust toolchain setup.
  • Type Mapping Strategy — Options for converting duckling Rust types to Ruby (serde_magnus vs. manual Magnus mapping vs. JSON round-trip), verified serde attribute analysis, and the target Ruby hash schema.
  • Test Coverage Research — Time corpus cases from duckling (1300+ lines), Ruby minitest test suite design with fixed reference time, and pyduckling parity scope for 0.2.0.
  • FFI Binding Risks — Hypotheses and Test Results — FFI binding risk analysis: GVL thread blocking (measured ~505µs/parse), panic safety (already mitigated by duckling), GC pressure, date rot (falsified through 2030), and Magnus 0.9 GVL API gaps.

Key Findings

Topic Critical finding
duckling-api Options::with_latent defaults to false — latent entities excluded by default. Grain::as_str() returns "no_grain" (not "nosec"). Entity has no dim field — derive :dim from entity.value.dim_kind().to_string().
build-wiring No build.rs needed in the extension crate; Magnus propagates rb_sys link metadata transitively. duckling IS on crates.io as duckling 0.4.0 — use duckling = "0.4".
type-mapping-strategy serde_magnus produces the wrong shape (externally-tagged enums, PascalCase grains). Manual Magnus mapping (Option B) is required. All hash keys and grain/type/dim values must be Ruby Symbols — use ruby.to_symbol("key") in Rust.
test-coverage Hill tests already written in PR #2 (test/duckling_test.rb); they assert symbol keys. Fixed reference time 2013-02-12 04:30:00 UTC-2 matches duckling corpus.
ffi-risks GVL hold measured at ~505µs for short inputs, ~3ms for long prose. Magnus 0.9 has no high-level GVL release API. Panic risk mitigated by duckling's own catch_unwind. Date rot hypothesis falsified (2030+ works). duckling does NOT validate day-of-week labels.

Clone this wiki locally