Skip to main content

Sources

Docs: Panes, Perceptions, Plots, Preferences, and Primary. Web App: Select a Page or Pane and open its Policies tab.

Structure

Policies answer two questions: which action and on which content. These are a Parable’s Policies. Every Page and Pane carries its own Policies as part of its definition. They are saved and versioned with it, so each Version of the Parable keeps the Policies it was published with. There is no separate Policy Piece to attach, share, or delete. The Workspace’s rules for Provider tables are a separate layer, Provider Policies. They apply first, to every read of a Provider table, and a Parable’s Policies can only narrow what they leave. Participants are separate from Policies. The Parable’s participants and their permissions are not versioned, so adding or removing a participant takes effect on the next request in every Version. A Page’s or Pane’s Policies govern it and everything it owns: A Plot and a Palette have no Policies of their own; their Page’s or Pane’s Policies govern them. A Page has no Plots. view and edit can name all six targets. create and delete name preferences, pane, plots, and palette. The Perception and Policies are fields of their Page or Pane: change them through edit; they are never created or deleted on their own.

Schema

All four action objects are required, and so is filters, which is always the empty list: a Page’s or Pane’s row filters are its filter Policies (below). Each target is independent: a missing or null target grants nobody access. An empty permission array also grants nobody access, including a Primary participant. Nothing inherits from another action or target.
participantPermission is an array of existing Parable permissions: peeping (Peeking), pinging, publishing, and primary. Matching any listed permission allows that action. Broader participation includes its subordinate permissions. Unknown fields, targets, permissions, and repeated permissions are refused. A grant can also name people and Workspace Roles in actors, a list of at most 50, each a person or a role with its id, none named twice. The grant then admits anyone a listed permission admits, each person it names, and anyone who holds a named Role in this Workspace:
A name admits only someone who holds a seat on the Parable: every action needs participation first, so naming someone without one reaches nothing. A Role counts while it exists and the person’s membership is active; a parent Role does not pass it down, and holding it in another Workspace does not count. A save that names someone who is not an active member of the Workspace, or a Role that does not exist, is refused. A name already saved stays when that person leaves or the Role is removed, and admits no one. A grant can also take its value from a This Parable setting with fromSetting, the Page’s or Pane’s key and the setting’s handle. This is how a Pane changes who may do something: it saves the setting, and the Policy reads it. The Pane that owns the setting types its Preferences as a grant with ParticipantGrant from parable/foundation, and says whether a change applies at once to every Version (Live) or only through a Version (Versioned):
Policies themselves are never live: they change only through a Version. What must change for every Version at once, such as an audience a Policies Page edits, is a Live setting a Policy reads. A setting a Policy reads whose Perception declares neither mode is named in its Warnings & Errors (PA-AU-050) and is Live until it does. See Preferences.
While the setting holds a valid grant that reads no setting itself, its value replaces the grant’s participantsWith and actors. A missing or invalid setting leaves the grant’s own, so the grant above admits the Primary until someone saves audience. The Page or Pane it names must be part of the same Parable. Changing or deleting the setting needs permission to edit the Policies that read it, as well as the setting’s own create, edit or delete.preferences, and its value must be a valid grant whose names belong to the Workspace. Every change is recorded with its value before and after.

Filter Policies

A Page’s or Pane’s Policies can hold filterPolicies: at most ten, each deciding which rows a reader reads of the Plots it covers, and which shared settings a writer may create, edit or delete on the Panes it covers. covers says what it covers: tree, the Plots of the Page or Pane that holds it and of everything that Page or Pane declares, at any depth, and a Page’s child Pages; or own, only the holder’s own Plots. A Pane no Page or Pane declares, and a Page under no Page, fall under the Parable’s Home Page, so a tree filter on Home covers every Pane of the Parable. A read applies every enabled filter Policy that covers the Plot’s Pane, joined by AND, so a Pane under two filtered Pages is held to both.
  • Audiences. A reader gets the union of the rules whose admits grant admits them: any all_rows reads every row; only hidden reads none; otherwise the rows where any rule’s conditions all hold. A reader no rule admits gets everyoneElse. The Primary always reads every row, so a condition every reader must meet, the Primary included, belongs in the Plot’s own SQL. A rule’s grant can name people and Roles and read a setting, like any grant.
  • The switch. enabled is the authored default. enabledFromSetting names a This Parable setting whose true or false turns the filter on or off for every Version at once; changing it needs permission to edit the Policies that read it, and every change is recorded.
  • Where it applies. Above the Plot a Pane asks for, and above each Plot your SQL names. Inside a Plot’s SQL, a Plot it reads applies the filters that do not also cover the outer Plot, which meet the rows above it instead, and every own filter that covers it, which applies at each read of its Plots. So no Plot reads past a filter by reading a filtered Plot from outside the filter’s reach.
  • Plots about people. A filter applies to a Plot that reads Provider data, directly or through the Plots and stored outputs it reads. Such a Plot must output every column the conditions read, usually identity_account_id: a read the filter binds is refused with QL-PL-015 until it does. The refusal names the filter in error.details.filter, and the Pane shows “Hidden by” and the filter’s name instead of an error. A Plot that reads no Provider table, only settings, Workspace tables or literal values, reads in full.
  • View as. A preview applies both people’s filter Policies.
  • Runs. A Report run applies none. Every reader of its stored output is filtered at read time.
  • Refreshes. A filter is access control, and access control is always current. Under a chosen Refresh the rows are that run’s, but the filter’s conditions, and the in_plot sets they read, read the data as it is now: a reader the reporting-chain filter narrows sees the Refresh’s rows for the people in their chain today. A filter never makes a Refresh unreadable.
  • actions. The verbs it narrows, one to four of view, create, edit and delete, as a database row policy names its commands. view narrows the rows of the Plots it covers. create, edit and delete limit the shared settings, This Parable’s and every group’s, of the Panes it covers: a writer such a filter binds may make that change only when the setting passes its conditions, which read the setting’s pane_key, handle, actor_kind, actor_id and value (JSON text). A create checks the new setting, an edit both the stored setting and the new one, and a delete the stored setting. The check runs as the writer, so an in_plot condition reads the writer’s own set, and a refusal names the filter. A writer’s own Me settings are never limited. A Pane’s policies.capabilities.writeConditional is true where such a filter binds the requester (Panes).

Services

The Policies tab shows the selected Page’s or Pane’s Policies. They arrive with the Parable’s contents; the editor makes no separate read. Ponder reads one Page’s or Pane’s Policies with read_piece_diagnostics, under the same view permission on Policies. The info glyph at the right of the tab’s header says that Page and Pane Policies apply to everything they own. The tab reads left to right in three columns, like drilling in. The first lists the Page or Pane, then each Pane it declares, as a tree: a Pane several Panes declare is listed once, under the first that declares it. Selecting one shows, in the third column, its own row of View, Create, Edit, and Delete. Each is the same picker a Pane’s audience rows use: Nobody, or a participation (Primary, Publishing, Pinging or Peeking) and any Workspace Roles and people it names. A participation admits everyone at or above it, so Pinging also admits Publishing and Primary participants; to narrow one, take away the participation above it. Each of the row’s choices sets that action on every part of the Page or Pane: View sets view on every part, and Create, Edit and Delete set that action on every part that has it. Edit never covers who may change the Policies themselves. When the parts differ, the choice reads Mixed, and one choice sets them all. Choices for a declared Pane save to that Pane’s Policies, and Open selects the Pane; saving a Page’s Policies does not change a Pane’s. Most Policies are set there. The second column, Advanced, lists the selected Page’s or Pane’s parts, each a row of its own: Preferences, Perception, Programming, Palette and Policies. Selecting a part shows its row in place of the Page’s or Pane’s own; selecting the Page or Pane again goes back to its own row. In a narrow drawer the two lists sit side by side above the row. Programming is who sees and changes the React code, its Plots’ SQL and their schedules; it follows the Page’s or Pane’s own row until it is set apart, to let people use or configure a Pane without seeing or changing how it is built. A Page’s Programming has no Plots. Who may change the Policies is set in the Policies row alone. Under a Page’s or Pane’s own row, its filter Policies are one list. Each row shows the filter’s name; the verbs it narrows (View, Create, Edit, Delete), each a toggle, at least one on; its switch; then Everyone except with the audience it never narrows, besides the Primary; then what everyone else keeps, Rows where its conditions hold, or Nothing. The conditions are chips: a column, an operator and a value, joined by AND, read from the columns every one of the Pane’s Plots returns for View, and from a setting’s columns (its handle, scope, group, Pane and value) for the other verbs. A condition only SQL can say, such as in_plot(...), shows as its SQL and is kept as written. Drag a row by the grip that takes its bullet’s place on hover, or move it with Space and the arrow keys; the order changes nothing, since every filter applies. Add filter starts a new one, which saves once it keeps something. A filter with several audiences of its own shows its name, verbs and switch, and leaves the rest to Ponder. A filter whose switch a setting holds (enabledFromSetting) shows the state that setting gives it and names the Page or Pane that holds the setting, as On, switched by Who sees what. The tab reads the settings its filters read in one read through the settings API, and reads them again when one changes; while the setting holds no value, the filter’s authored enabled applies, as it does on the server. The switch shows that state and does not change it, and the row is never drawn as off while the setting turns the filter on. The settings API leaves out a setting you may not read (one on a Page or Pane whose view.preferences you lack, or on one the Parable no longer holds) while the server still applies it, so the tab asks whether you may read the holder’s settings. Until the setting is read, and wherever you may not read it, the row names it, as Switched by Who sees what, and shows no state. A grant that reads a This Parable setting names it under its choice, as From setting rename of Changes for everyone. Once that setting is saved, it decides who is admitted; the choice sets who is admitted until then, and choosing keeps the setting each part reads. A filter’s Everyone except audience reads its setting too. While the setting holds an audience, the row shows that audience, which the server admits in place of the filter’s own, and its picker is locked: From setting seesEveryRow of Who sees what. While the setting holds none, the picker shows and sets the filter’s own audience, and a choice keeps the setting: Until setting seesEveryRow of Who sees what is saved. While the tab cannot tell, it shows the filter’s own audience and says so: Unless setting seesEveryRow of Who sees what is saved. Each choice saves as it is made, like the rest of the definition: Personal mode saves the working definition directly, and Publishing mode saves it to Changes, which take effect when published. A new filter saves once it has a name, a verb and something to keep. If the Policies changed elsewhere after you started, your draft is kept and the panel offers to apply it to the latest Policies or discard it; for a declared Pane, the panel names that Pane. The tab does not save a choice that would leave you, or anyone, unable to edit the Policies again; it marks that choice and says why. When you may not change the Policies, the controls are off and the tab’s header reads Read-only. When you may not see them, it reads Policies hidden; if you may still change them, Replace starts a complete replacement at your own participation.

Security

Source inspection of a published Version follows the Policies the line holds today and the requester’s current participation. Selecting an older Version does not recover access to SQL, React, or Perception source that current Policies hide. Settings also follow current Policies. A Live setting is not part of a Version. A Versioned setting is part of each Version: a reader of an older Version reads that Version’s value, and a Policy reads the current Version’s. On an installed Parable, the current definition includes the exact Version the Workspace accepted and its own changes. Publishing a newer upstream Version does not change that pin. A local Policy override takes precedence over the inherited Policy, and a deleted Piece cannot recover access through its base. A Pane’s React receives resolved decisions in props.policies; they guide the interface and never authorize a request. A reader without view.policies does not receive the Policies text. View as decides by the previewed person’s participation alone. A Page’s or Pane’s grant that names them, or a Role they hold, does not apply in the preview, since it may admit them where it does not admit you. A filter Policy row that names them or their Role does apply: such a row can narrow what they read, and your own filter Policies still apply beside theirs, so the preview never shows you more than you read. Creating a Page or Pane needs a participant who may edit the Parable; the Policies it carries do not authorize it. Restoring a deleted Page or Pane is judged by the Policies it held when it was deleted. Restoring unchanged content needs delete.pane. Changes made during restoration also need their usual permissions: edit.pane for the Page or Pane and its React, edit.perception for Perception, edit.plots or create.plots for Plots, edit.palette for its Palette, and edit.policies for Policies. Omitted owned parts return with their stored source and identities. If the retained content needed to check a restore is unavailable, the restore is refused. Without recorded Policies, only the Primary may restore it. Changing Policies needs edit.policies under the Policies already in force. Policies in a draft or in an incoming Version cannot approve their own installation. A delete retains the Page’s or Pane’s stored Policies. Sending different Policies with a delete, including a repeated delete, cannot change who may restore it later. Source changes require a live Piece; a save cannot hide a source edit behind a deleted owner. view.plots governs SQL source inspection; view.pane governs React source inspection. A permitted Pane can render without granting source-editor access. Rendering React or CSS delivers executable code or styles to the browser, so this distinction does not promise secrecy for those assets. SQL stays on the server while permitted readers consume its output. A Plot’s rows follow its Pane’s Policies: view.preferences decides who may read them, and the filter Policies that cover it narrow them. Plot output stays read-only even if the Policies grant create, edit, or delete. A restriction that must hold for every read of a Provider table, in every Parable and in SQL, belongs in that table’s Provider Policy, not in one Pane’s Policies. Filters further restrict rows; they never grant an action. For example, a Pane’s own filter can leave each reader but the Primary only the rows belonging to their email:
A filter’s conditions read the result columns of the Plots it covers; a Provider Policy uses the same language on the table’s columns. Conditions do not authorize replacement of the Policies themselves. Unsupported or invalid conditions refuse execution. See Execution context for current filter and Report limits.

Reference

Generated Workspace API reference for this Piece: