Skip to main content

Sources

Docs: Panes, Plots, Policies, and Preferences. Web App: Refresh, at the top right of the Parable editor, chooses a data reading: Latest (the API’s Current) or one stored Report run, which the UI calls a Refresh. It lists every stored run; a run that is not complete carries its status and has no rows to read. The choice rides in the address as refresh. Pane code reads the host’s coordinates through getParableContext(). In Publishing mode, View as, the icon beside it, previews the Parable as one member of its Workspace.

Structure

A definition identifies code and schema. A data reading identifies Current data or one Report run. React and SQL use the same context so a page can display an older Report with a newer compatible definition without confusing the two.
The host supplies the authenticated identity. Selecting another actor’s scenario changes an input; it does not impersonate that actor. A View as preview is the one case where the context names someone else, and the server, not the page, decides it (see View as).

Schema

TypeScript and Rust share this generated data model. A context names either a commit or a ref with revision, never both. props.policies separately supplies resolved Pane decisions; context fields and displayed capability booleans are not credentials. A saved Plot’s result.meta identifies the data that actually answered it. For example, Current can resolve to Report R42 produced by definition v6 while meta.context still describes the consuming v7 definition. The returned reading identifies R42; changing the definition label would not make its data compatible.

Services

The Pane SDK binds requests to the host-selected definition and reading. It resolves source identities on the server, so a named SQL read does not require downloading private SQL. It also uses resolveParablePanes to resolve explicit values and policy decisions; hidden or unavailable items return individual refusals without discarding their permitted siblings. SQL reads the same context:
A query without a Parable definition can inspect its verified principal:
principal.email, when present, comes from the authenticated account. Neither Provider identity matching nor an application parameter can replace it. Unknown context fields fail planning. parable_context() requires a trusted Parable context; it does not invent a default identity. When definition, reading, or authority changes, the host replaces the relevant bindings and ignores responses from the earlier selection. Draft requests can carry expectedRefRevision; a stale revision conflicts rather than running old code with a new label. Proposing a set of Changes leaves the line’s revision where it is, so a reader of the line is never refused because someone else proposed their set. A Plot read that pins no revision reads the definition as it stands: when a publish or a save moves the ref while it runs, web-api reads it once more at the new revision and answers from that, rather than refusing it. That covers web-api’s own revision checks (PA-AU-002) and the Query Layer’s check that the context it was handed still holds (gRPC Aborted). It reads again once only (PARABLE-5946). Separate Current queries remain live and do not promise one atomic snapshot across the whole page. Positional SQL parameters remain separate from context. Omitting an override uses saved values; an explicit array replaces them. Existing Report data keeps its captured inputs and refuses a different override. Parameters cannot change the requester, Workspace, definition, or policy decisions. Ponder’s Pane pictures use a captured reading with the requester’s verified context, Pane references, and policy decisions. They can read only the captured settings; they cannot run live SQL or write values. A missing or denied required reference makes the picture unavailable. The picture does not invent an actor, version, or permission to complete a render.

Security

Workspace surfaces check an active membership on a live account, Parable participation, and current Policies on the server. A deleted account keeps no access through a seat it still holds. Admin Ponder can inspect a definition and reconstruct its context for an active staff account without granting Workspace membership, after the Admin Ponder permission, selected Workspace line, direct RACI seat, and current Policies pass. Definition edits remain governed by the Policies of the Page or Pane they change. Selecting an Admin Workspace keeps the same authenticated account. Plot planning, including preparation for publication, and live SQL execution still require that account’s active Workspace membership. Definition access alone does not authorize those operations; a direct RACI seat or Admin role cannot replace membership.

View as

A participant who holds Publishing or Primary on a Parable can preview it as one active member of its Workspace. A preview never shows anything the previewer could not read themselves:
  • The person’s seat on the Parable must be at or below the previewer’s.
  • The preview runs as that person: principal, actor and raci name them, their seat decides every Page’s and Pane’s Policies, and request_principal() and filter Policies read them. Their own settings stay theirs and are not shown; the settings shared for This Parable follow their Policies. A Page’s or Pane’s grant that names them or a Role they hold does not apply in the preview. A filter Policy row that names them or their Role does apply, since it can narrow what they read; your own filter Policies apply beside theirs.
  • viewAs names the previewer while a preview runs, and is null otherwise. Every change is refused during a preview, so a Pane shows read-only controls when context.viewAs is set.
  • Provider data must pass both people’s Provider Policies. Query Layer evaluates the person’s rules and the previewer’s own and keeps only rows both admit, so a preview cannot read a source the previewer could not.
  • The definition on screen stays the previewer’s: their draft or the Version they chose.
  • SQL run inside the Parable, from a Lab Page or Ponder’s SQL tool, reads only its Plots, whoever may edit them (Plots).
The page starts a preview with POST /api/parable/authoring/primaries/{rootRefId}/view-as, naming a personId from GET …/view-as/targets. web-api records the start in user_event (parable.view_as.start, with the previewer, the person, the Parable and the Workspace) and returns the event’s id. Every read of the Parable then carries only that id in X-Parable-View-As; web-api reads the person back from its own record and checks the previewer and the person again on each request. A preview ends after eight hours. A request that carries the id and changes anything is refused with PA-AU-044; a preview that is refused, over, or for another Parable answers PA-AU-048. web-api passes the previewer to Query Layer beside its service token (viewAsViewerId on a Plot read, and on the x-parable-caller-bin caller entry of an immediate query), and Query Layer caps the principal’s rank on that line at the previewed seat. Ponder, the model, keeps working as the previewer and never acts as the previewed person. The host resolves request coordinates and strips untrusted context metadata before forwarding queries. A prepared query or page cursor cannot be reused under another actor, definition, or reading. Returned policy authorityKey values invalidate stale presentation; they do not authorize writes. A preview is governed by its actual inputs. A named Plot read also applies its Pane’s Policies. Source restrictions run before projection, joins, aggregation, and limits. A SQL alias cannot remove an attached rule. For example:
An absent email does not match. A missing governing policy, unsupported evaluator, or invalid condition refuses access. A Provider Policy’s conditions receive that table’s columns; a filter Policy’s receive the result columns of the Plots it covers. The current filter language accepts scalar conditions and ANDs them together; volatile functions, placeholders, aliases, and subqueries are refused. A scheduled Report executes as the Workspace’s explicit principal. It does not borrow its creator’s credentials, and no Provider Policy narrows it. The Workspace usually holds no seat on the line, so the run takes its participation from the Parable’s Accountable seat: it starts only while the person in that seat, or an active member of the role that holds it, may run the Report, and it computes with that seat’s rank. When the Workspace itself holds the Accountable seat, the run starts on the Workspace’s own seat. web-api checks this when it captures each occurrence. Every participation check the Query Layer makes for the run, its run scope and each Plot’s Source Policies included, names the run (platform.report_run_id) and reads the seat again (workspace.parable_participant_rank_for_principal). On another Parable the run reads, the Workspace ranks as the people in the run’s own Accountable seat rank there, never as that Parable’s own Accountable seat; when the Workspace holds the run’s own seat, it has only its own seats there. With no run named, the Workspace has only its own seats. The database does not check permission to edit Parables again during a run: it lends participation, which a person holds with or without that permission, and web-api’s check at each occurrence decides whether the next run starts. A manual Report uses the authenticated requester, whose authority is checked when execution starts. A requester whose Provider Policies narrow a Provider table the Report reads is refused, because the run would store only their rows for everyone who opens it.

Stability

Pipeline Current, which the Refresh menu calls Latest, reads the latest completed compatible Report. Selecting a Refresh keeps that exact run, and missing or incompatible data is refused. So is a stored Refresh that read a Provider table the reader’s Provider Policies narrow: it holds rows they can’t read. Report provenance stays separate from the selected code version and from current access. Provider input replay is not implemented. A historical result with a request_principal() Provider filter requires its captured principal, including email. A Provider filter using full parable_context() currently refuses Report materialization. Deleting or hiding a captured input can make the result unavailable. A Pipeline can read another Pipeline of the same Report. The run is a graph: a member runs after the members it reads and reads what they wrote in this run, under the same execution context. Members that read each other in a cycle are refused. A Pipeline can also read a Plot nothing stores, which the run reads as a view of its SQL (Plots read as views). Ordinary SQL and previews can query completed Pipeline results with either Current or an explicit Report selection; an explicit Report selection reads what that run stored and never a view’s live rows.