Sources
Docs: Panes, Perceptions, Policies, Plots, and Workspace Pool. Web App: A Pane’s own controls save a setting when you choose to keep it, such as a date range or a pivot, and show it again when the Page reloads.Structure
A Preference is a setting: a value that a person saved for one Pane, for themselves, shared for the whole Parable, or shared for one group. A chosen date range, a pivot layout, a selected team, and a theme choice are settings. The value has the type of the Pane’s Perceptionpreferences field, and the Pane’s code names each setting with a handle, such
as dateRange. A Plot that reads a Pane by name reads its setting under the
handle preferences (Plots). A Perception
that does not declare preferences types its settings by its primitive, as
every Perception did before preferences existed.
Every setting has one scope, and the product names it the same way wherever a
scope is shown or chosen:
A shared setting is held per Parable: each Workspace’s copy of a Parable has
its own shared settings, so the scope reads This Parable, not Workspace.
A group is any group of people the Parable’s own data describes, at any level
of its hierarchy: in Team Time Spend, a Division, a Department or a Team. The
levels and their names come from the Parable’s content, so a Workspace whose
organization has other levels gets those, and nothing in the platform depends
on a level. A group setting names its group by the ID a Plot of the Parable
gives it, such as a category’s ID, in the canonical form the API returns; Parable keeps no list of
groups, so a Pane offers the groups its own Plot reads. When the scope is
chosen, show one section per level, named as the Parable names it, listing
that level’s groups.
A Workspace’s Parable holds at most one setting for each Pane, handle, and
scope, and one for each group. This Parable, each group and a person can each
hold a setting under the same handle.
Parable does not fall back from one scope to another; the Pane’s code decides
which to show. Most Panes let the most specific win: a person’s own setting,
else the deepest group they belong to, then each level above it, else This
Parable’s. A Pane that offers several, such as Hide for Me and Hide for This
Parable, labels each choice with its scope.
Preferences hold settings: the values that fill a Parable’s Pieces when it
runs. The app itself — its Pages, Panes, Perceptions, Policies, Palettes, and
Plots — is versioned with the Parable and changes only through the authoring
save or a published Version. The app’s defaults belong in the Pane’s code and
Perception. A setting never changes the app’s React, CSS, or the text of its
Policies, though a Policy can read one (Security). The one setting
that holds code is a Plot’s SQL, below, and it changes only through a Version.
Live or Versioned
Each Page’s or Pane’s settings are Live or Versioned, and its Perception says which by wrappingpreferences in Live<T> or Versioned<T>
from parable/foundation:
The mode covers every handle of the Page or Pane. A Perception that wraps
preferences in neither is Live, as every setting was before modes existed;
say so with Live<T> when a Policy reads the setting (Security).
Because the declaration is part of the Perception, choosing a mode is itself a
change to the Parable: it saves into your Changes like any edit, or straight to
the Parable when it is Personal. The Preferences tab beside Policies
lists each setting with its scope, its mode, its value and who set it, and its
How changes apply switch edits the declaration for you. It lists the
settings of the selected Page or Pane and of every Pane it declares, at any
depth, each under its Pane, as the Policies tab walks them; the switch then
names whose mode it sets, as How Toolbar’s settings change, since it sets
the selected Page’s or Pane’s mode alone and each listed Pane shows its own. A
Pane whose Perception declares preferences and holds no saved setting shows
Default: its code’s default applies. A Page holds no settings of its own,
so a Page’s tab offers no mode and lists its Panes’ settings. A Perception that
declares preferences: null keeps no settings, so its tab offers no mode
either, says so, and lists the settings of the Panes it declares. When nothing
the tab lists can keep a setting, it says No settings rather than waiting
for one.
A Versioned setting belongs to the Parable, so it has only shared scopes: This
Parable and a group. A save for Me on a Versioned Pane is refused
(PA-AU-040).
Plot SQL saved as a setting. A Pane whose Perception declares
readonly preferences: Versioned<PlotSql> keeps its Plot’s SQL as its setting,
under the Plot’s handle. A save of it is the Plot’s new SQL in a new Version,
so the Plot gate checks it, and each Version keeps the SQL it was published
with. Such a Pane has no other settings, and its Plot may not be named
preferences. Plot SQL is always Versioned: Live<PlotSql> does not compile.
Saving it needs edit.plots as well as edit.preferences, as editing the Plot
does, and reading it needs view.plots.
Services
Pane code saves and reads its own settings through thepreferences.values
binding of its generated module. The binding belongs to the calling Pane; it
cannot read or write another Pane’s settings. Rendering and reading never
create a setting.
A setting saved before its Pane’s Perception changed can stop fitting the
Pane’s type, for example when a field it lacks became required. A read leaves
that setting out: list returns the Pane’s other settings, and get returns
null, so the Pane shows its defaults in its place. The Parable’s window says
A saved setting no longer fits and the Pane’s name once, with whose setting
it was. The setting stays stored, and delete still removes it. While it is
stored, a save of the same handle as a new setting (expectedRevision: 0) is
refused as a revision conflict.
The Workspace API has five operations, and Ponder can use each as a tool:
A save names the Pane, the handle, whether the setting is shared, the group
for a group setting, an optional name and icon, the value, and
expectedRevision. A group setting is shared, so it sets shared and names
the group in group:
expectedRevision: 0 creates the setting and is refused if one already exists.
Any other number replaces the value that revision read. The save returns the
setting’s ID and new revision, not the value, and its outcome.
A save or delete of a Versioned setting also takes release, minor (the
default) or major, and an optional message that describes the change. Who
makes the change decides what happens:
A Live setting’s
outcome is live, and it ignores release and message.
In Pane code, preferences.mode reads live or versioned and
preferences.plotSql reads whether the settings are Plot SQL; both come from
the Perception and cannot be changed from code:
PREFERENCE_WRITE_PENDING,
and the window says Still saving your change with Refresh. When the
Version is published, the window says Updated to v1.84. Everyone else with
the Parable open hears of the new Version at once: a reader on the newest
reading sees Updated to v1.84, and a reader of an older Version sees
v1.84 is available with a link to it.
IDs are Identity UUIDs in the canonical base62 form the API returns. Pass the
IDs that reads and saves return rather than a hyphenated UUID.
Storage
A Live setting takes effect at once and keeps its history. It is not part of a Version: publishing does not copy, reset, or roll it back, and reading an older Version reads today’s value under today’s Policies. A Versioned setting’s values are part of its Page or Pane, so each Version and each set of Changes holds its own. The API reads the values of the definition you are viewing: List and Read takerefId or versionId, as Save does. When a
Version is published, its Versioned values become the settings SQL and Policies
read, so workspace.preferences, a Policy’s fromSetting and a Report run read
the current Version’s values. A Version published before a Pane’s settings
became Versioned reads their live value.
The server checks every value against the Pane’s preferences (else its
primitive) when it is saved. A value that does not match is refused
(PA-AU-040). Selecting a saved value to render a Pane checks it against that
definition’s setting type too. Changing that type does not rewrite existing
settings; an incompatible selection is refused until its saved value is updated.
A Plot reads settings with plain SQL through workspace.preferences. It returns
the settings the person running the query can read for the selected Workspace
and Parable: their own (Me), and the ones shared for This Parable or a group
whose Pane’s view.preferences Policy allows them, as the settings API decides.
id, parable, pane_key, handle, actor_kind,
actor_id, name, value, revision, and updated_at. actor_kind names
the scope: person for Me, workspace for This Parable, and group for a
group setting, whose actor_id is the group’s ID (the stored names predate the
product’s). Filter on it when a query needs one scope, since a handle can match
one row for each. To let the most specific win, keep per handle the reader’s
row, else the row of their deepest group, else This Parable’s:
my_groups stands for the Parable’s own Plot of the groups the reader
belongs to, one per level, with each level’s depth counted from the top.
actor_id reads as the canonical ID text, so a Plot that derives group IDs
returns them in that form; parable_cast_identity_uuid turns a hyphenated
UUID into it. value is JSON text, which a Plot parses with the JSON
functions. A Report run reads the shared settings, This Parable’s and every
group’s, as they were when the run was captured, never a person’s own. The run
reads the ones its principal may read; a person viewing the run reads the ones
they may read now. A Plot with its own
schedule or materialization cannot read the table. See Workspace Pool
for both, with an example.
Security
Settings need an active Workspace membership on a live account. A suspended, revoked, or missing member, or a deleted account, reaches no settings, even with a seat on the Parable. A person’s setting is theirs alone: nobody else can read, change, or delete it. A shared setting belongs to This Parable and follows the Pane’s current Policies on the line:view.preferences permits reading, create.preferences
permits creating, edit.preferences permits replacing, and delete.preferences
permits deleting. These are separate grants; editing does not imply creating or
deleting. Selecting an older Version does not restore its former grants.
Every save and delete carries the revision you last read. A newer revision
refuses the write (PA-AU-002); read the setting again and retry without
losing your draft.
A setting is data unless a Policy reads it. A grant in a Page’s or Pane’s
Policies can take its value from a This
Parable setting (fromSetting). Changing or deleting that setting also needs
permission to edit the Policies that read it, its value must be a valid grant,
and every change is recorded. Any other setting grants nothing, and no setting
changes the app’s React, CSS, or the text of its Policies.
A setting a Policy reads decides who may do what, so its Perception must say
whether it is Live or Versioned. Until it does, the Page’s or Pane’s
Warnings & Errors name it (PA-AU-050), and it is Live. Choose Live when a
change must reach every Version at once, as an audience a Policies Page edits
usually must; choose Versioned when a change of who may do what should be
reviewed and published like the rest of the Parable.
The server reads a setting’s mode from the Parable as it is now, never from the
Version being read or from the caller, and enforces it on every save and
delete, whichever Pane, tool or API makes it. Removing someone
from the Parable’s participants removes their access to its shared settings on
their next request.