# Issue 979 Preview Synthetic Read Overlay Split

Status: implemented scope split for PR #980; follow-up issue #1044.

## Restatement

Issue #979 adds a server-side, no-DML preview endpoint for registry-backed
standard actions. The endpoint lets a create UI ask the backend, "if this
standard action runs with this input, what parent and child records would the
Flow prepare before Save?"

The endpoint must be authoritative for the supported subset:

- it shares the standard-action preparation path;
- it executes Flow metadata without committing records;
- it returns only read-authorized preview fields;
- it publishes `previewEndpoint` only for Flow shapes that the no-DML runtime
  can preview faithfully.

The fix is not to simulate every database read/write behavior in #980. The
safe #980 boundary is standard-action create preview for create graphs whose
later metadata does not depend on reading preview-created rows as if they were
durable database rows.

## Current Problem

The pre-split branch included a synthetic `recordLookup` overlay so a later
Flow lookup could see earlier preview-created rows. Codex Review correctly
identified that this is a larger substrate than #980 can safely own:

- Lookup-mediated synthetic IDs are not fully tracked as synthetic provenance.
- Synthetic lookup rows are appended after the live query path has already
  applied read/RLS/FLS projection, so raw preview fields can influence later
  Flow branches or copied values in ways live execution would not permit.

That makes the preview API look authoritative while relying on a partial read
overlay. The right split is to move synthetic read overlay support to a
follow-up PR and keep #980 fail-closed.

## #980 Scope

#980 should keep:

- standard-action preview discovery and route;
- singular preview request/response contract;
- no-DML insert preparation through `PreviewBeforeInsert`;
- parent/child response shaping with read-side projection;
- fail-closed capability detection for unsupported Flow elements;
- synthetic preview IDs only as internal Flow output-reference wiring, not as
  durable record existence.

#980 should remove or disable:

- synthetic `recordLookup` result overlay;
- any capability claim that a later `recordLookup` can safely observe a
  preview-created row;
- any capability claim that active before-create automation with `recordLookup`
  can safely observe earlier preview-created rows;
- tests whose success depends on lookup seeing preview-created rows.

## #980 Implementation Plan

1. Remove the synthetic lookup overlay call from `executeRecordLookup`.
2. Delete or quarantine `flow_preview_lookup_overlay.go`.
3. Change `StandardActionCreatePreviewSupported` to fail closed when a
   previewable Flow graph contains both a `recordCreate` and a `recordLookup`
   in the same reachable preview graph. This is intentionally conservative; a
   path-sensitive checker can come later.
4. Treat created-object before-create flows with `recordLookup` as unsupported
   until synthetic reads can share the production read projection path.
5. Keep the existing synthetic-ID checks for direct references, assignment
   propagation, child-flow outputs, action calls, and subflow inputs.
6. Replace the lookup-overlay regression with a capability regression proving
   `create -> lookup by natural key -> create` does not publish
   `previewEndpoint`.
7. Update `issue-979-flow-owned-create-preview.md` to say lookup-after-create
   preview is deferred.

## Follow-Up PR Scope

Issue #1044 and its follow-up synthetic read overlay PR should own the real
substrate:

- request-scoped preview write set with provenance;
- read-side projection through the same object permission, RLS, and FLS paths
  as durable `QueryService` reads;
- child-flow scoping rules so internal standard-action read scopes do not leak
  into non-pack-owned child flows;
- lookup result typing and ID provenance so `preview-*` IDs cannot be treated
  as durable parents outside the same preview write set;
- uniqueness / validation / formula / inheritance reads that can see the same
  simulated state live execution would create;
- path-sensitive capability discovery that advertises preview only when every
  later read has overlay parity.

### PR #1045 Provenance Guard

The first safe substrate slice keeps `lookup-after-create` preview discovery
fail-closed, but adds request-local plumbing for the records-layer readers that
can already consume synthetic rows. That plumbing must not let a caller forge a
preview parent by sending a predictable string.

Runtime synthetic IDs therefore use this no-DML-only shape:

```text
preview-<128-bit-random-hex>
```

The token is minted inside the preview executor with `crypto/rand` before the
ID is registered in the request-local synthetic record registry. Records-layer
short-circuits may consult that registry only for IDs minted and registered
during the current preview run. If entropy cannot be read, preview fails closed
with an internal error rather than falling back to a predictable ID. Caller
literals such as `preview-Account-1` fall through to the durable
validation/read path and fail the same way live execution would.

The #1044 implementation can then re-enable preview for
`create A -> lookup A -> create B` patterns only when the lookup consumes
synthetic rows after the production query layer has applied object access,
record access, and field projection. Unsupported lookup operators, filter
logic, missing projection support, and created-object before-create lookups
remain fail-closed so preview prefers false negatives over
authoritative-looking false positives.
