> ## Documentation Index
> Fetch the complete documentation index at: https://docs.parable.work/llms.txt
> Use this file to discover all available pages before exploring further.

# Preferences

> Select and store typed application values and Pane content explicitly.

## Sources

Docs: [Perceptions](/ponder/parables/pieces/perceptions), [Plots](/ponder/parables/pieces/plots), and [Policies](/ponder/parables/pieces/policies).

Web App: A Pane's value picker selects saved records. Its Plots and Policies documents edit the selected content when permitted.

## Structure

A Preference stores an application value or saved SQL, React, or CSS content.
Policy rules and app-owned Policy bindings are versioned definitions. A record has an ID, a type, a value, current
Policies, and a revision. Sharing a table does not give all records the same
permissions: editing application Preferences cannot authorize changes to SQL,
React, CSS, or policy settings.

A **Use** groups records for a particular purpose and declares their value type
and cardinality. The app's versioned Policy definitions govern access:

| Cardinality   | Allowed records                                           |
| ------------- | --------------------------------------------------------- |
| One           | At most one record in the Use. It may be unfilled.        |
| One per actor | At most one record for each associated actor kind and ID. |
| Many          | Multiple records, including several for the same actor.   |

A list inside one value is one record, with one revision and one set of Policies.
Multiple records have independent identities, values, and access checks.

Source editors identify **Saved Preference** and **App definition** separately.
Saving a Preference updates that live record and confirms **Saved live**.
**Promote to App definition** copies the selected saved revision into the app:
Personal mode confirms **Saved to Personal**, while Publishing confirms
**Saved to Changes**. Publish activates those Changes. A later edit to the
Preference does not change the copied definition. Save or discard unsaved source
text before promoting a revision.

Promotion requires permission to view the saved source and edit the destination
definition. SQL includes its saved parameter defaults. React belongs to its
owning Pane, and CSS belongs to that Pane's resolved Palette. Changing
collaboration mode preserves Versions and live Preference history without
publishing or including live values in a Version.

Saved SQL can include parameter defaults. Its Plot input contract governs those
values. Activating or publishing an incompatible input contract is refused while
old defaults remain. Remove the incompatible defaults explicitly, activate the
new contract, then save replacement defaults that match it. Saving a draft does
not rewrite live defaults.

## Services

Use `preferences.values` for a Pane's application data. Its value type comes
from that Pane's `Perception['primitive']`, including native Dates. Reads return
record metadata and typed values; writes return an identity and revision without
requiring permission to read the value back.
Record and Use IDs accept UUID or base62 form. The host compares their scalar
identity and still checks that each returned record belongs to the requested Pane.
The generated SDK also pins its compiled primitive fingerprint. The host and
Store refuse a missing or changed fingerprint, including for empty collections.
Writes check that fingerprint in the same transaction as the record and Use,
then validate the value against both the selected and active contracts. These
checks do not require permission to read a value before creating or editing it.

Direct API callers requesting typed guarantees supply `expectedPaneKey` together
with `expectedPrimitiveContractHash` from the selected runtime binding. Ordinary
untyped configuration requests keep their existing behavior.

For a Pane whose primitive is `{ name: string }`:

```ts theme={null}
import { preferences } from '@parable/demo/people';

const use = await preferences.values.createUse({ cardinality: 'many', name: 'People' });
const saved = await preferences.values.create({
  useId: use.id,
  value: { name: 'Ada' },
  isDefault: false,
});
const person = await preferences.values.get(saved.id);
console.log(person.value.name);
```

The typed surface also provides `list`, `getDefault`, `listUses`, `update`,
`delete`, `deleteUse`, and `setDefault`. Its Uses always belong to the Pane that
exports it. A saved source, configuration record, or another Pane's Use cannot
become application data by passing its ID. External IDs remain subject to the
same checks. Rendering and reading do not create Uses or records.

The host-bound `preferences` SDK uses explicit operations:

| Read                  | Write                                                                         |
| --------------------- | ----------------------------------------------------------------------------- |
| `get(id)`             | `create(input)`                                                               |
| `list(useId)`         | `update(id, input)`                                                           |
| `getDefault(useId)`   | `delete(id, expectedRevision)`                                                |
| `listUses(filter)`    | `createUse(input)`, `updateUse(id, input)`, `deleteUse(id, expectedRevision)` |
| `history(id)`         | `setDefault(useId, input)`                                                    |
| `readPolicies(input)` | Policy changes use the definition save flow.                                  |

`getDefault` returns the visible default or no value. An absent or hidden default
never selects the first record, the current actor's record, or a Workspace
record. There is no My/Workspace fallback order. Reads never create a value.

Creating a record validates its native type and checks the existing destination's
creation authority. An update needs the revision last read and must satisfy both
the current and proposed value checks. Deleting needs `delete` permission for
that record's content target and its current revision.

Cardinality and default selection belong to the Use. Changing them is a
collection-configuration edit; permission to add or edit one member does not
automatically grant that operation. Setting a default checks the Use revision,
and a nonempty Use cannot be deleted. Concurrent writes that violate cardinality
or overwrite a newer revision are refused.

Use `readPolicies` to load the selected Policy definition and current eligibility for a
Pane, saved source, or SQL output. It does not require downloading that source
or reading its binding configuration. Hidden settings are returned as null;
resolved decisions remain separate. See [Policies](/ponder/parables/pieces/policies)
for the save contract.

Pane resolution uses the selected definition revision. If a save or publication
change advances it while the request is in flight, the API returns a source
conflict (`409`, `PA-AU-002`); refresh the context before requesting its current
eligibility. An older decision never bypasses the current Policies.

## Storage

Live application records follow the current Perception. Selecting an older
Parable definition does not permit writing a value that violates the current
application schema. Editing definition source uses the authoring and publishing
workflow; editing an independent saved Plot uses its record revision.

SQL exposes permitted records through `workspace.preferences`. For an explicitly
selected Use, `preferences('<Use UUID>')` exposes native `record` metadata and
`value` columns. The value type comes from the Use's compiled Perception, even
when it has no records. Select object fields with expressions such as
`value['name']`; filters apply before joins, aggregates, projection, and limits.
Numbers remain numeric SQL values, and nullable values retain the nullability
declared by their Perception, including referenced types and array elements.

A Report captures the visible membership and values of every Use it reads,
including an empty collection. Later edits do not replace those captured values.
Reading the result checks captured inputs against current Policies; deleted or
newly hidden inputs can make it unavailable.

Report schedules are live Preferences independent of publication. Editing a
schedule does not publish the Parable; publishing does not restore older schedule
settings. A queued Report produces its outputs before becoming complete.

## Security

Saved application Preferences require a current account and active membership in the Workspace.
A retained Parable participant assignment does not restore access after that
membership is suspended, revoked, or removed. Preference reads, writes, Pane
resolution, and SQL execution enforce this same prerequisite. Writes keep the
membership and account locked through their transaction so revocation cannot
race a stale grant into a commit.

Authored defaults and source in the Parable's package follow authoring access. Staff with
permission to view the Workspace can read those definitions without Workspace
membership, provided they hold a seat on the Parable and its Policies allow the
read. This does not grant access to saved application Preferences.

An associated actor describes the record. It does not impersonate the requester,
grant ownership, or make the record private. A Person and a Workspace are distinct
actors even if their IDs match. If an application permits only an actor's own
record, its conditions must compare both actor kind and ID with the trusted
requester.

The server identifies the content target from saved type and owner metadata.
A caller cannot label SQL as an ordinary application Preference to use
`edit.preferences` instead of `edit.plots`. Policy changes and app-level reattachments
use the versioned definition flow and prior authority; proposed settings cannot authorize themselves.
Saved JSON that resembles a Policy does not grant access, and the Preference
API cannot replace or reattach live Policy rules.

## Reference

Generated Workspace API reference for this Piece:

* [List Preferences in a use](/protocols/reference/web-api/parable-authoring-list-parable-preference-records)
* [Create a Preference](/protocols/reference/web-api/parable-authoring-create-parable-preference-record)
* [Read a Preference](/protocols/reference/web-api/parable-authoring-read-parable-preference-record)
* [Change a Preference's value](/protocols/reference/web-api/parable-authoring-update-parable-preference-record)
* [Delete a Preference](/protocols/reference/web-api/parable-authoring-delete-parable-preference-record)
* [Read a Preference's past values](/protocols/reference/web-api/parable-authoring-read-parable-preference-record-history)
* [List Preference uses](/protocols/reference/web-api/parable-authoring-list-parable-preference-uses)
* [Create a Preference use](/protocols/reference/web-api/parable-authoring-create-parable-preference-use)
* [Change what a Preference use accepts](/protocols/reference/web-api/parable-authoring-update-parable-preference-use)
* [Delete a Preference use](/protocols/reference/web-api/parable-authoring-delete-parable-preference-use)
* [Read the default Preference](/protocols/reference/web-api/parable-authoring-read-default-parable-preference)
* [Set or clear the default Preference](/protocols/reference/web-api/parable-authoring-set-default-parable-preference)
