Skip to main content

SPEC.md

# SPEC — live_interaction_contracts (v1, frozen)

This document holds **durable statements only**. No version-specific numbers appear
here; those live in the harness output (`delegation-ledger.json`) and the dated
`reports/*_REPORT.md` evidence files. If a sentence here would change when LiveView ships a
new version, it does not belong in this file.

## Three evidence tiers (kept separate everywhere)

1. **Durable invariant** — true by the architecture's construction, independent of
   implementation. Lives in `SPEC.md` / `KERNEL.md` / the `*_CONTRACT.md` files.
2. **Observed version-specific behavior** — what a tested LiveView/browser version
   did. Lives in `delegation-ledger.json` (generated) and `reports/*_REPORT.md` (dated).
3. **Conformance result** — pass/fail produced by the harness on each run. Lives in
   CI output and the regenerated ledger.

Never copy tier-2 numbers into tier-1 prose.

## Durable project statements

1. **This project is not a component library.**
2. It defines **executable interaction contracts** for Phoenix LiveView and
   browser-native state machines.
3. **Components are derivations of contracts**, not the primary artifact.
4. The **conformance harness and delegation ledger are first-class artifacts.**
5. **LiveView DOM node continuity is observed implementation behavior, not a
   documented framework guarantee.** The LiveView docs describe `phx-update` with the
   verb "replace" and make no promise of DOM node-object persistence.
6. **The harness exists to detect regressions in that observed behavior** — it is the
   fuse that converts statement 5 from a footnote into a monitored contract.

## The one cross-cutting invariant

> **A delegated browser machine is patch-safe only when its state does not live in a
> server-reconciled attribute, and any structural attribute it requires is a
> server-rendered constant.**

Both halves are load-bearing and both are evidenced (see `RED_FIXTURES.md` and
`REFERENCE_POPOVER_CONTRACT.md`). This is why popover is green and dialog/details are
red.

## v1 verdict

**Frozen (will not change without the invalidation evidence below):**

- the durable kernel invariants (`KERNEL.md`)
- the delegation-ledger **format** and classification rules (`DELEGATION_LEDGER.md`)
- the conformance harness (`CONFORMANCE.md`)
- **CI-as-fuse** — stable gate + main/edge early-warning (`CONFORMANCE.md`)
- the reference popover / tooltip / menu / select / combobox contracts
- the cursor contract and channel contract, including the shipped
  `LiveInteractionContracts.Channel` guard
- anchored `placement` presets for the reference components (zero-JS CSS anchor
  positioning, with documented browser-floor degradation)
- the amber dialog-adapter contract (`CONTRACT_DIALOG.md`), 7/7 conformance-gated

**Explicitly NOT frozen:**

- a polished public `<.dialog>` / `<.details>` component API (the dialog *adapter*
  contract is an amber reference — `CONTRACT_DIALOG.md` — but no component ships)
- any IME correctness claim (only synthetic events tested)

**Still experimental:**

- native select popup state (not automatable)
- real-device IME behavior (the synthetic no-emit-during-composition rule is frozen;
  device coverage is not)

**Evidence that would force a v1 revision:**

- the harness showing a **green machine regress** on any supported LiveView version
  (node continuity or top-layer survival changes) → ledger + kernel update
- a **red fixture turning green** (LiveView stops stripping reflected attributes) →
  it may graduate out of `RED_FIXTURES.md`
- a delegated machine found whose state is safe **despite** living in a
  reconciled attribute, or unsafe **despite** not → the cross-cutting invariant is wrong
- a client-owned coordination need that **cannot** be met by stable-logical-id +
  explicit rebind → the Interaction Persistence split is wrong
- real-device IME showing the "no emit during composition" rule is insufficient →
  the Channel contract's IME clause needs revision

## Scope of applicability

These contracts pay rent only at the **interaction-primitive boundary** (overlays,
menus, comboboxes, focus/scroll coordination). For ordinary CRUD / forms / navigation
LiveView, the traditional two-runtime model is adequate and this project is silent.