# live_interaction_contracts

Executable interaction contracts for Phoenix LiveView.

This package checks whether browser-native interaction state survives LiveView
patches. It ships a conformance harness, a delegation ledger, and a small set of
unstyled reference components that are backed by those contracts.

Use it when you need to know whether a popover, menu, tooltip, select, combobox,
dialog adapter, focus handoff, or async query shell is safe under LiveView DOM
patching.

## Why this exists

LiveView gives the server authority over rendered HTML, but many interaction
machines keep their state in the browser: top-layer popovers, active descendants,
focus, selection, pending input, and listbox shells.

The hard failures happen when both sides think they own the same state. A patch
replaces a node, a client hook rebinds, the server renders stale results, or the
browser keeps state that the server cannot observe.

`live_interaction_contracts` turns those cases into executable contracts. Each
green claim is backed by browser tests across Chromium, Firefox, and WebKit.
Amber and unknown cases stay explicit.

## What ships

- A Mix task that runs the conformance harness against real browsers.
- A generated delegation ledger that classifies each state machine as green,
  amber, red, or unknown.
- Reference components for `<.popover>`, `<.tooltip>`, `<.menu>`, `<.select>`,
  and `<.combobox>`.
- A `LiveInteractionContracts.Channel` helper for monotonic async query results.
- Contract documents that define the state ownership rules.

The components are intentionally unstyled. They are reference primitives, not a
finished UI kit. The future UI kit direction is Temper UI; this package is the
proof layer underneath it.

## Install

For harness, ledger, and CI use:

```elixir
{:live_interaction_contracts, "~> 1.0", only: [:dev, :test], runtime: false}
```

If you also use the reference components at runtime:

```elixir
{:live_interaction_contracts, "~> 1.0"}
```

The harness requires `elixir`, `node`, and Playwright browsers:

```sh
npx playwright install chromium firefox webkit
```

The reference components require Phoenix LiveView 1.1 or later. Their client JS
ships as Phoenix colocated hooks. After `mix compile`, register the extracted
hooks in your `app.js`:

```javascript
import {hooks as licHooks} from "phoenix-colocated/live_interaction_contracts";

new LiveSocket("/live", Socket, {hooks: {...hooks, ...licHooks}});
```

## Reference component example

```elixir
defmodule MyAppWeb.Demo do
  use Phoenix.Component
  use LiveInteractionContracts.Components

  def demo(assigns) do
    ~H"""
    <.popover id="demo" placement="bottom">
      <:trigger>Open</:trigger>
      <:content>Patch-safe by contract.</:content>
    </.popover>
    """
  end
end
```

## Run the harness

Run these commands from your Phoenix project:

```sh
# all stable browser engines
mix live_interaction_contracts.test

# one browser
mix live_interaction_contracts.test --browser chromium

# one suite
mix live_interaction_contracts.test --suite combobox

# early warning against LiveView main
mix live_interaction_contracts.test --lv "github:phoenixframework/phoenix_live_view#main"

# regenerate the delegation ledger
mix live_interaction_contracts.ledger

# advisory app audit for patch-safety and dual-write risk
mix live_interaction_contracts.audit --path /path/to/app

# compare two harness result sets
mix live_interaction_contracts.compare --a before.json --b after.json
```

By default, the harness tests against your project's LiveView version.

## Current v1 coverage

Green reference machines:

- Popover
- Tooltip
- Menu
- Select
- Combobox
- Cursor coordination
- Versioned async query channel

Amber:

- Dialog adapter, with documented restrictions.

Unknown:

- Native select popup open-state.
- Real-device IME behavior.

## Read next

- `SPEC.md`: v1 frozen scope and project claims.
- `KERNEL.md`: the state ownership model.
- `CONFORMANCE.md`: harness and CI behavior.
- `BUILDING_COMPONENTS.md`: how to add the next contract-backed component.
- `PROJECT_MAP.md`: where the detailed evidence lives in this repository.
