---
title: "radiatR design contract"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{radiatR design contract}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include=FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

```{r setup}
if (requireNamespace("pkgload", quietly = TRUE)) {
  # Always load from source so the vignette reflects the current development state.
  pkgload::load_all("..", export_all = FALSE, helpers = FALSE, quiet = TRUE)
} else if (requireNamespace("radiatR", quietly = TRUE)) {
  library(radiatR)
} else {
  stop("Package 'radiatR' not installed and 'pkgload' not available.")
}
```

radiatR keeps a tidyverse-shaped surface: data flows as plain tibbles addressed
by column name, and rich objects are reserved for structure a flat table cannot
hold safely.

## Rich objects, only where structure is irreducible

- `Tracks` — trajectories with arena geometry, a per-trajectory reference
  frame, and transform history (invariants a bare tibble cannot enforce).
- `circ_display()` — an orientation convention (zero direction, rotation).
- `circ_regression()` — a fitted model (like `lm`).

## Everything else is a plain tibble, in and out

Plain tibbles are addressed by a column-name argument (`angle_col = "heading"`).
The `circular` package's `circular` objects are an internal implementation
detail — built inside functions, never in a public signature or return.

## `headings_frame`: a dplyr-durable tibble subclass

`headings_frame` is a tibble subclass that carries the display convention
durably through dplyr verbs (via the `dplyr_reconstruct` contract), so a
`mutate()`/`filter()` never silently drops the orientation. Read its metadata
with the `hf_*` accessors. A plain data frame with a heading column is always an
acceptable substitute — the class is an enhancement, never a requirement:

```{r}
data(cpunctatus)
hd <- derive_headings(cpunctatus, rule = "distal")
hd2 <- dplyr::filter(hd, is.finite(heading))   # class + display preserved
class(hd2)
hf_display(hd2)
```
