# Flow Issue Remediation Plan (2026-04-26)

## Purpose

This document is the review draft for the current **Flow repair wave**. It
serves two layers at once:

1. a **first-wave implementation plan** for the highest-priority `UAT-Test`
   issues
2. a **broader backlog map + architect discussion draft** for the wider open
   `module/flow` backlog

It answers five questions:

1. Which issues are **single-point fixes** versus **structural design work**?
2. What is the proposed **repair strategy** for each first-wave issue?
3. How should the **broader open issue set** be grouped into repair clusters?
4. What is the proposed **triage / sequencing hypothesis**?
5. Which items should be treated as **downstream umbrella consumers**, not as
   first-wave Flow engine work?

This plan is based on:

- [flow-system-overview.md](./flow-system-overview.md)
- [flow-engine-gap-analysis.md](./flow-engine-gap-analysis.md)
- issue set: `#1456`, `#1464`, `#1465`, `#1469`, `#1511`, `#1539`, `#1792`

## Scope

This is a **repair-planning** document, not an implementation spec.

It intentionally separates:

- **Flow substrate work**: runtime primitives, metadata contracts, scheduler,
  action execution boundary, evaluator integration
- **Flow consumer work**: business flows, forms, layouts, email content, launch
  stage rollout

That separation is important because several current issues are labeled
`module/flow` but are not best solved by changing the generic Flow engine first.

### In scope

- first-wave planning for 7 selected `priority/P0` / `priority/P1` +
  `UAT-Test` issues:
  - `#1456`, `#1464`, `#1465`, `#1469`, `#1511`, `#1539`, `#1792`
- broader mapping of the wider open `module/flow` backlog into architectural
  repair clusters
- classification logic
- proposed sequencing
- architect-review questions for substrate versus consumer boundaries
- metadata-driven guardrails for choosing repair direction

### Scope model

This document now uses **two coverage levels**:

1. **Detailed design coverage**
   - the 7 first-wave issues above
2. **Cluster-level remediation coverage**
   - the broader open `module/flow` issue tail, grouped by same-root repair
     shape

That means:

- the first-wave 7 issues have **detailed proposed plans**
- the broader issue set has **cluster-level mapping, sequencing hypotheses, and
  architect discussion prompts**
- this document still does **not** claim that every lower-priority issue has an
  individually frozen implementation spec yet
- the broader cluster sections below are **not** execution-ready design
  contracts and must not be used as implementation baseline without a
  follow-up design slice that explicitly adds Salesforce baseline, candidate
  paths, repo evidence, declared delta, next-tenant impact, and verification

For the broader historical/runtime inventory, reviewers should also consult:

- [flow-system-overview.md](./flow-system-overview.md)
- [flow-engine-gap-analysis.md](./flow-engine-gap-analysis.md)
- [issue #1825](https://github.com/pingcap-inc/MetaDrivenPlatform4AI/issues/1825)
  for the 12-cluster umbrella triage snapshot

---

## 1. Confirmation Status

This document distinguishes three confidence levels:

- **Confirmed**
  - repo evidence and issue evidence are already strong enough to treat the
    statement as the current working fact
- **Suspected**
  - evidence points in one direction, but implementation work should not assume
    it is settled until an explicit repro / code-path confirmation is complete
- **Pending architect decision**
  - multiple reasonable designs remain; proceeding without a decision creates
    avoidable rework risk

### 1.1 What is already confirmed

1. The Flow subsystem is no longer only a record-automation runtime; it also
   acts as the execution substrate for flow-native standard actions.
2. The current design boundary should separate:
   - Flow execution graph semantics
   - standard-action invocation contract semantics
3. `#1456`, `#1464`, and `#1465` are substrate-level issues, not isolated
   business-flow patches.
4. `#1539` and `#1511` are downstream business/consumer issues and should not
   be allowed to define generic runtime shape by accident.

### 1.2 What is still suspected

1. `#1792` is probably a bounded engine/event-path defect, but this is not yet
   proven strongly enough to treat it as a settled point fix.
2. `#1469` may be bridgeable in the short term through Flow or metadata-driven
   populators, but only if the semantic delta and exit mechanism are made
   explicit.

### 1.3 What still needs architect confirmation

1. `#1464`: durable scheduled-path model
2. `#1465`: shared sender contract and reuse boundary
3. `#1469`: whether a tactical bridge is acceptable, and under what explicit
   constraints

### 1.4 First-wave design-contract register

The tables below are the compact version of the design-review gate for the
first-wave issues. They are not the full implementation spec, but they do make
the load-bearing claims auditable before coding starts.

| Topic | Salesforce baseline / candidate paths | Repo evidence checked | Declared delta / why | Next-tenant impact | Verification anchor |
|---|---|---|---|---|---|
| `#1792` trigger classification | Salesforce-style record-trigger execution should not need object-specific branches; the first decision is whether the bug is bounded dispatch drift or a broader event-pipeline problem. Candidate paths: focused event-path fix vs reclassified shared-state repair. | `backend/internal/features/automation/flow_trigger_listener.go:307-368` shows update-path matching already exists for `CreateAndUpdate`; staging issue comments still report the symptom as open. | No intended product delta is being frozen here; the delta is in confidence only: current repo evidence is insufficient to lock this as a point fix without a fresh repro. | Next tenant should not need Lead-specific branches to make AfterSave update flows fire. | local repro on `main`, staging repro, and regression coverage for PATCH update + convertLead update + blocked negative control |
| `#1456` formula resources | Candidate paths: no formula support, Flow-local parser, or shared formula engine integrated into Flow execution. | `backend/internal/features/automation/executor_helpers.go:91-116` defines `evaluateFlowFormulas`; `backend/internal/features/automation/flow_executor.go:606-612` calls it on the resume path before execution continues. | Declared delta: current `main` already chose “shared evaluator integrated into Flow runtime”; remaining work is validation/dependency/production-proof closure, not a second evaluator design. | Next tenant should author Flow formulas as metadata without requiring per-flow code hooks. | activation-time validation tests, resume/TODAY-NOW refresh evidence, and production-shape lead-assignment regression proof |
| `#1464` scheduled paths | Salesforce baseline: record-triggered scheduled paths are platform-managed deferred work with automatic cancellation/rescheduling when later record changes alter the scheduling conditions. Candidate paths: dedicated scheduled-job table vs extending `FlowInterview` as the durable owner for deferred branches. | `shared/pkg/models/salesforce_flow.go:214,550-556`, `backend/internal/features/automation/scheduler_service.go:105-109`, and `backend/internal/features/automation/flow_interview_service.go:194-224` capture the current metadata hook, wake-up primitive, scheduler polling, and paused-interview claim/resume semantics. | Declared delta: no durability model is frozen yet; review posture starts from `FlowInterview` reuse as the hypothesis to beat so we do not invent a second durable state authority without named necessity. Any design must explicitly name how later record updates cancel/reschedule existing pending work for the same record/path, or else declare a conscious NexusCRM delta from Salesforce and justify it. | Next tenant should get the same deferred-execution contract from metadata, including predictable update-time cancellation/rescheduling semantics rather than tenant-specific async behavior. | persistence-model comparison note, chosen-lifecycle tests, cancellation/rescheduling tests across repeated record updates, fire-time filter re-evaluation tests, retry/idempotency evidence |
| `#1465` template + sender contract | Candidate paths: separate template/send mini-engine vs reuse of generic Flow resource resolution plus a stronger shared sender primitive. | `backend/internal/features/automation/approval_service.go:1975-1988` shows the current sender helper's weak fallback semantics; `backend/internal/features/automation/executor_actions.go:72-79` routes `emailAlert` through ApprovalService while `backend/internal/features/automation/executor_actions.go:93-119` keeps `emailSimple` on the generic action execution path; the structural split is expanded in this doc's `#1465` section at `docs/design/flow/flow-issue-remediation-plan-2026-04-26.md:536-567`. | Declared delta: ApprovalService helper is a reference point, not the final contract; Flow needs an explicitly stronger sender contract for org-wide addresses and workflow-user semantics. | Next tenant should be able to vary sender policy and template metadata without new handler code. | template rendering tests, sender-resolution contract tests, and explicit failure-path coverage for unregistered sender / permission denial |
| `#1469` tactical bridge | Candidate paths: true computed-field substrate, temporary metadata-driven bridge, or permanent denormalized Flow workaround. | The bridge semantics and exit constraints are expanded in this doc's `#1469` section at `docs/design/flow/flow-issue-remediation-plan-2026-04-26.md:621-697`; the metadata-driven boundary against preserving a long-lived runtime bridge is anchored in `CLAUDE.md:183-189`. | Declared delta: if a bridge is allowed, it must be temporary, field-bounded, and have an explicit exit trigger; otherwise it becomes a second long-lived computation system. | Next tenant must not inherit a hidden Flow-based denormalization subsystem as the default data model. | named field list, bridge-scope tests, exit-trigger issue, and durable follow-up ownership decision in records/metadata |
| `#1539` umbrella decomposition | Candidate paths: let rollout issue drive substrate shape vs decompose into consumer slices that depend on repaired substrate. | The dependency mix and decomposition boundary are expanded in this doc's `#1539` section at `docs/design/flow/flow-issue-remediation-plan-2026-04-26.md:719-753`, which explicitly ties this umbrella to `#1464` and `#1465` instead of letting it author the substrate contract. | Declared delta: this issue should stay a downstream consumer umbrella, not silently become the Flow runtime contract author. | Next tenant rollout issues should consume the generic substrate instead of baking business rollout shape into the engine. | child-issue map plus dependency matrix to substrate capabilities |

---

## 2. Architect Confirmation Matrix

The goal of this matrix is to make the remaining architecture questions easy to
answer decisively, so implementation can proceed with less churn.

| Topic | Current status | Why not settled yet | What needs explicit confirmation | What work becomes safe after confirmation |
|---|---|---|---|---|
| `#1792` classification | Suspected point fix | issue evidence says symptom is real, but repo evidence does not yet prove the failing layer | Whether current `main` repro shows a bounded dispatch/execution-boundary defect or a broader event-pipeline/shared-state problem | safe scoping of the fix as either one focused PR or a structural repair track |
| `#1456` formula resources | Direction mostly settled | main open risk is lifecycle details, not overall architecture | memoization scope, validation boundary, and Wait-resume policy | implementation split and contract tests |
| `#1464` scheduled paths | Pending architect decision | durable state model changes execution architecture | dedicated scheduled-job table vs FlowInterview reuse; cancellation/rescheduling after later record updates; retry/idempotency expectations; kill-switch semantics | persistence model, worker design, PR decomposition |
| `#1465` template + sender contract | Pending architect decision | current helper semantics are weaker than the desired Flow contract | exact delta from current ApprovalService helper; shared primitive vs extracted/replaced primitive | sender-resolution implementation without semantic fork risk |
| `#1469` tactical bridge | Pending architect decision | temporary bridge can easily become permanent drift | temporary semantic delta from Salesforce behavior, allowed scope, owner, and exit trigger | minimal bridge PR or explicit deferral to records/metadata design |
| `#1539` umbrella decomposition | Pending architect decision | issue mixes metadata, runtime, async, reporting, email | whether to decompose first and which child tracks are prerequisite-gated by substrate work | business rollout sequencing with less rework |

### 2.1 Confirmation-first principle

For the items above, the immediate goal is **not** “start coding as soon as
possible.” The immediate goal is:

1. confirm the smallest stable contract
2. freeze the key boundary decisions
3. only then start implementation on the pieces that are no longer ambiguous

This is especially important for `#1464`, `#1465`, and `#1469`, where the cost
of coding before confirmation is likely to be rework, not learning.

---

## 3. Classification Method

### 3.1 Single-point fix

Classify an issue as a **single-point fix** when all of the following are true:

- one broken invariant is clearly identifiable
- the failure lives in a bounded code path
- no new metadata surface or durable runtime primitive is needed
- the fix can be proven by a small regression set
- the change should fit in one focused PR or one small PR wave

Typical examples:

- trigger dispatch path missing one branch
- one resolver path returns the wrong value
- one evaluator edge case is inverted

### 3.2 Structural design issue

Classify an issue as **structural design work** when any of the following are
true:

- it needs a new runtime primitive
- it needs a new persistent table / queue / worker / scheduler contract
- it adds or redefines a metadata boundary
- multiple business flows depend on the same substrate capability
- the correct fix must be split across multiple PRs with staging / rollout gates

Typical examples:

- formula resources
- scheduled paths
- text template rendering pipeline
- standard-action or email sender contract changes

### 3.3 Umbrella / downstream consumer

Classify an issue as an **umbrella or downstream consumer** when:

- it aggregates multiple scenarios across modules
- it depends on one or more Flow substrate features but does not itself define
  the substrate
- the right first step is decomposition, not direct coding

Typical examples:

- launch-stage framework
- generic form-validation umbrella

---

## 4. Issue Classification

| Issue | Class | Why |
|---|---|---|
| `#1792` | Suspected single-point fix, gated on repro | likely bounded defect, but classification must be confirmed against current `main` and staging behavior |
| `#1456` | Structural design | flow-level formula resource substrate |
| `#1464` | Structural design | deferred execution / scheduled-path runtime |
| `#1465` | Structural design | template rendering + sender contract + polymorphic resolver |
| `#1469` | Structural design with tactical bridge | immediate migration pressure exists, but durable fix is not a one-line Flow patch |
| `#1511` | Umbrella consumer, not Flow-first | frontend form validation issue; Flow label is incidental |
| `#1539` | Umbrella consumer, not Flow-first | business rollout framework depending on several substrate features |

---

## 5. Recommended Priority Order

### Tier 0: Immediate correctness / triage

1. `#1792`

### Tier 1: Core Flow substrate

2. `#1456`
3. `#1464`
4. `#1465`

### Tier 2: Migration bridge + data-model follow-up

5. `#1469`

### Tier 3: Downstream consumer decomposition

6. `#1539`
7. `#1511`

### Why this order

- `#1792` is a live correctness bug, not a speculative feature gap.
- `#1456` is the smallest high-leverage substrate gap and is a dependency for
  part of `#1465`.
- `#1464` is the major async runtime gap and should be designed before pushing
  more business flows that depend on deferred execution.
- `#1465` should land after formula semantics are settled; otherwise template
  rendering gets forced to invent a second evaluation path.
- `#1469` has tactical value for migration, but its durable answer depends on a
  platform decision about computed-field semantics, not just a Flow patch.
- `#1539` and `#1511` should not dictate Flow runtime shape. They should
  consume the repaired substrate rather than drive it.

---

## 6. Single-Point Fix Plan

### 6.1 `#1792` AfterSave flow not fired on Lead Update

Issue: [#1792](https://github.com/pingcap-inc/MetaDrivenPlatform4AI/issues/1792)

### Current understanding

- The issue is still open and recent staging comments say the reported fix did
  not actually close the bug.
- The observed symptom is specific to `RecordAfterSave + CreateAndUpdate` for
  the **update** half, but the exact failing layer is not yet proven.
- Repo evidence does **not** currently prove that the root cause is a missing
  `CreateAndUpdate` matcher branch in the listener. The listener code path
  already appears to match update events for `CreateAndUpdate`; see
  [flow_trigger_listener.go](../../../backend/internal/features/automation/flow_trigger_listener.go#L307-L368).
- The problem may instead live in:
  - event-pipeline behavior after matching
  - detached transaction / outbox boundary behavior
  - convert-path update plumbing
  - staging deployment drift versus current `main`

### Proposed repair plan

1. Reproduce on current `origin/main` locally with a focused engine test.
2. Compare local behavior with staging behavior.
3. Inspect the exact code path for:
   - direct PATCH update
   - convertLead-triggered Lead update
   - outbox / detached transaction / post-save worker path
4. Only after that classification, choose one of two paths:
   - if the root cause is a bounded dispatch / execution-boundary defect,
     proceed as a focused point fix
   - if the root cause is event-pipeline or shared-state contract drift,
     reclassify the issue as Tier-1 structural work before coding
5. Add three non-negotiable regressions:
   - manual PATCH update
   - convertLead update
   - negative control where start filter blocks
6. Re-verify on staging with the issue repro script before marking fixed.

### Repair shape

- **Preferred shape:** one focused PR
- **Gating rule:** only if repro proves the defect is actually bounded
- no metadata migration unless repro uncovers a missing metadata contract

### Acceptance bar

- scenario 2 and scenario 3 in the issue both pass on staging
- no regression on create path
- explicit evidence that both direct update and convert path traverse the same
  supported AfterSave update contract

### Architect review focus

- confirm whether this can honestly remain classified as a point fix after
  repro on current `main`
- confirm whether `DetachTx` / async boundary assumptions are still correct on
  current `main`

---

## 7. Structural Design Plans

### 7.1 `#1456` Flow `<formulas>` resource evaluation

Issue: [#1456](https://github.com/pingcap-inc/MetaDrivenPlatform4AI/issues/1456)

### Why this is structural

- the feature is business-critical across multiple flows, so it still needs a
  disciplined closure plan even though the baseline evaluator path has landed
- affects decisions, lookups, assignments, actions, and future template
  rendering
- remaining work is concentrated in validation, dependency handling, and
  production-shape regression proof

### Proposed design direction

- Reuse the existing/shared formula engine rather than create a Flow-only parser.
- Treat the current `main` implementation as the baseline:
  - Flow formulas are already evaluated into interview context at executor entry
  - resume already refreshes those formulas before execution continues
- Do **not** reopen evaluator plumbing unless a concrete failing case proves the
  current hook points are insufficient.
- Focus the next wave on what is still missing:
  - activation-time validation
  - dependency/cycle guards
  - duplicate resource-name rejection
  - production-shape end-to-end proof on the lead-assignment flows
- Add activation-time validation for:
  - unsupported functions
  - dependency cycles
  - duplicate resource names

### Proposed PR split

1. **PR-A: validation + dependency graph**
   - cycle detection
   - duplicate-name guard
   - activation/runtime error shaping
2. **PR-B: production-shape regression + contract proof**
   - lead-assignment flow case
   - roundtrip / tooling regression
   - resume / TODAY-NOW refresh evidence

### Current baseline already on `main`

- `evaluateFlowFormulas()` writes formula results into `interview.ContextData`
- `executeFlowMetadata()` re-runs formula evaluation on every resume entry
- downstream elements consume those names through the normal context resolution

So the planning target here is **closure of the remaining correctness and
validation gaps**, not re-introducing a second evaluator design track.

### Design constraints

- no second formula language
- no business literals in Go
- no one-off per-flow injection path

### Architect review focus

- memoization scope for Wait resume
- null semantics and coercion policy
- whether formula results belong only in executor memory or also in persisted
  interview context

---

### 7.2 `#1464` Record-triggered scheduled paths

Issue: [#1464](https://github.com/pingcap-inc/MetaDrivenPlatform4AI/issues/1464)

Focused design follow-up:

- [flow-scheduled-path-design-1464.md](./flow-scheduled-path-design-1464.md)

### Why this is structural

- adds a new async execution mode
- needs durable queueing / state / worker behavior
- redefines trigger-time versus fire-time semantics
- is one of the clearest boundaries between durable workflow mode and atomic
  action mode

### Proposed design direction

Do **not** implement scheduled paths as an ad hoc bolt-on inside the trigger
listener.

Instead:

- model scheduled paths as a durable async job layer owned by the Flow runtime
- persist durable pending work per `(record, scheduled-path)` in a way that lets
  later record updates cancel, replace, or reschedule earlier pending work
- re-fetch record state at fire time
- re-evaluate original start filters at fire time
- run scheduled branch in its own transaction
- keep this feature strictly in **durable workflow mode**

Salesforce baseline to preserve unless a delta is declared explicitly:

- scheduled paths are not just “fire later if still relevant”
- when later record updates change the scheduling conditions or schedule time,
  the platform automatically cancels and/or reschedules existing pending
  scheduled work

That means a design that simply accumulates one durable job per trigger event
and relies on fire-time self-skip semantics is not automatically equivalent.
If NexusCRM intentionally chose that weaker model, the doc would need to
declare it as a product-boundary delta, justify it, explain next-tenant
behavior, and define verification. This plan does **not** currently recommend
that weaker model.

### Important deviation from the raw issue spec

The issue body proposes a dedicated `_System_FlowScheduledJob` table and a new
worker. Architect review should not accept that as the default blindly,
because the current runtime already has a durable wake-up primitive in
`FlowInterview.PausedUntil` plus scheduler claim/resume machinery.

So the first decision is not “which new queue table should we add?”, but:

- can scheduled paths be modeled by extending/reusing `FlowInterview`
  persistence without introducing a second durable state authority?
- if not, what exact mechanism is missing that makes a dedicated scheduled-job
  table necessary?

Default review posture:

- start from **FlowInterview reuse as the hypothesis to beat**
- allow a dedicated scheduled-job table only if the design note names the
  concrete mismatch and why it cannot be solved cleanly on top of
  FlowInterview

Evidence a separate table would need to provide:

- which invariant cannot be represented with `FlowInterview` + `PausedUntil`
- why one-trigger-many-branches cannot be modeled as one durable interview per
  scheduled branch
- how later record updates cancel, supersede, or reschedule pending work for
  the same `(record, scheduled-path)` key
- why observability/accounting requirements cannot be satisfied by extending
  interview state instead of adding a parallel queue

Only if that evidence is written down should the design switch to a dedicated
scheduled-job table.

### Proposed PR split

1. **PR-A: persistence-model decision + metadata closure**
   - compare `FlowInterview` reuse vs dedicated scheduled-job table
   - write down the winning durability contract and the evidence for it
   - name the cancellation/rescheduling mechanism for later record updates
   - complete `FlowScheduledPath` model
   - roundtrip tests
2. **PR-B: enqueue path on the chosen durability model**
   - trigger listener computes fire-at
   - enqueue or replace pending scheduled work using the chosen persistence
     shape
   - mixed immediate + scheduled path behavior
3. **PR-C: worker/resume path on the chosen durability model**
   - poller / claim / execute / skip / fail lifecycle
   - cancellation / supersession behavior across later record updates
   - filter re-evaluation
   - observability hooks
4. **PR-D: admin/debug visibility**
   - pending-job visibility if needed for support

If architect review concludes a dedicated scheduled-job table is truly required,
that table + indexes should first appear in **PR-A** as the output of the
decision step above, not as a pre-decided starting point.

### Design constraints

- no in-memory-only queue
- no fake sleep-based implementation
- no atomic-flow support for scheduled paths

### Architect review focus

- scheduled-job table vs FlowInterview reuse
- cancellation / rescheduling semantics after later record updates
- stale record semantics at fire time
- retry / idempotency policy
- kill-switch behavior

---

### 7.3 `#1465` TextTemplate rendering + OrgWideEmailAddress sender

Issue: [#1465](https://github.com/pingcap-inc/MetaDrivenPlatform4AI/issues/1465)

### Why this is structural

- adds a rendering pipeline, not just one more email field
- depends on resource resolution rules
- touches email sender contract
- introduces polymorphic reference semantics in templates

### Proposed design direction

Split the problem into three layers:

1. **Template rendering layer**
   - render `TextTemplate` resources as strings
   - resolve resource references through the same resolver stack as executor
2. **Action parameter resolution layer**
   - resolve template/formula references before dispatching `emailSimple`
3. **Sender resolution layer**
   - reuse the ApprovalService sender path only as an extraction starting point
   - declare and implement an explicitly stronger Flow-side sender contract

### Dependencies

- depends on `#1456` for a clean shared resource-resolution story
- does not strictly depend on `#1464` as a platform feature
- but the target partner-convert flow needs all of `#1456 + #1464 + #1465`

### Proposed PR split

1. **PR-A: TextTemplate evaluator**
   - plain-text / HTML rendering
   - unresolved token behavior
2. **PR-B: `emailSimple` integration**
   - resolve template and formula references before send
   - action parameter integration tests
3. **PR-C: sender resolution**
   - `OrgWideEmailAddress`
   - `DefaultWorkflowUser`
   - shared resolver extraction if needed
4. **PR-D: polymorphic reference support**
   - only if existing nested resolver cannot safely support `Owner:User.Email`

### Delta from current code

The current plan says "align Flow email sender resolution with ApprovalService
behavior", but that phrase needs to be precise:

- the current `ApprovalService.resolveSenderAddress` helper is useful as a
  directional reference and likely extraction point; see
  [approval_service.go](../../../backend/internal/features/automation/approval_service.go#L1975-L1988)
- it is **not** sufficient as-is for the stricter Flow contract proposed here

The Flow-side implementation therefore needs an explicit semantic delta:

- validate `OrgWideEmailAddress` against registered metadata
- declare and enforce the permission policy for sending as that address
- resolve `DefaultWorkflowUser` explicitly
- forbid silent fallback to the SMTP/system default when the action metadata
  requested a stronger sender contract

This should be implemented as an extension or replacement of the shared sender
resolver, not as a second unrelated sender mini-contract.

### Design constraints

- no separate “template mini-engine” with different semantics from Flow
- no silent fallback from unregistered OrgWideEmailAddress to CurrentUser
- no hardcoded sender/business address in Go

### Architect review focus

- whether polymorphic reference handling belongs in generic resolver or
  template-specific resolver
- HTML escaping policy
- permission model for org-wide sender addresses

---

### 7.4 `#1469` Denormalized formula-cache columns

Issue: [#1469](https://github.com/pingcap-inc/MetaDrivenPlatform4AI/issues/1469)

### Why this is not a pure single-point fix

- the issue spans many fields and objects
- the real question is whether these fields should behave like:
  - read-time formula fields
  - write-time denormalized caches
  - migration-only bridge columns
- the answer affects records/modeling, not only Flow

### My split for this issue

There are two valid tracks, and they should not be conflated:

#### Track A: tactical migration bridge

Use a **small, explicitly temporary** set of BeforeSave/AfterSave flows or
metadata-driven populators for the few fields that block near-term migration.

This track is acceptable only if:

- it is limited to a named field list
- every field is justified by a real business flow
- the document states this is a bridge, not the final semantic model
- the semantic delta from Salesforce Formula behavior is declared explicitly
- there is a mechanical exit trigger, not just a good intention

#### Track B: durable platform decision

Decide whether NexusCRM will support true computed/formula fields at the object
model level.

If yes:

- this should be designed in the records/metadata layer
- Flow should consume that substrate, not simulate it field by field

If no:

- formalize a metadata-driven denormalized-cache mechanism
- likely outside Flow proper, because parent updates need controlled fanout and
  replay semantics

### Required semantic declaration for Track A

Track A must explicitly choose one bridge semantic:

- **snapshot-on-child-write**
  - child-side cached field is refreshed only when the child itself is written
- **refresh-on-parent-change**
  - parent changes must fan out to children through a controlled propagation
    mechanism

My current recommendation is to treat any bridge as
**snapshot-on-child-write unless a field-specific review proves otherwise**.

Reason:

- it is the smallest temporary semantic delta
- it avoids pretending we already provide true Salesforce formula-field behavior
- it keeps the bridge visibly narrower than a durable computed-field model

The document should be honest that this differs from Salesforce read-time
formula semantics.

That delta should be called out in any implementation PR and tested as a
deliberate temporary product behavior, not left implicit.

### Recommended plan

- **Short term**: approve a tactical bridge for the minimum blocking fields
- **Medium term**: open a separate design track for computed-field semantics
- **Do not** let this issue force the generic Flow engine to become a catch-all
  denormalization layer

### Exit mechanism for Track A

Track A should only be approved if all of the following are committed in the
implementation plan:

1. a named field list in the bridge PR
2. a companion follow-up issue for the durable model
3. a removal trigger:
   - either computed-field platform support lands
   - or a records/metadata-layer denormalized-cache primitive lands
4. a cleanup/data-spec or equivalent removal plan for the temporary bridge

Without those four items, the bridge should be considered non-compliant with
the project's metadata-driven and legacy-remediation rules.

### Proposed PR split

1. **PR-A: field audit + minimal bridge list**
2. **PR-B: bridge implementation for the minimal list**
3. **PR-C: follow-up design doc for computed-field strategy**

### Architect review focus

- whether denormalized cache semantics belong in Flow at all
- parent-update propagation model
- whether the platform wants read-time formulas versus stored caches

---

## 8. Umbrella / Downstream Consumer Plans

### 8.1 `#1539` FY26 Launch Stage framework

Issue: [#1539](https://github.com/pingcap-inc/MetaDrivenPlatform4AI/issues/1539)

### Why this should not be solved as one Flow issue

This issue mixes:

- picklist / metadata changes
- immediate transitions
- date-based delayed transitions
- reporting/dashboard
- email alert
- record-type-specific policy

So it is not “a single Flow feature.” It is a business rollout depending on
multiple layers.

### Recommended decomposition

Split into child tracks:

1. stage metadata / record-type matrix
2. immediate Flow transitions
3. deferred auto-refresh transitions
4. dashboard/reporting
5. email alert

### Flow-specific implication

This issue should wait for:

- scheduled/deferred execution strategy from `#1464`
- email/template strategy from `#1465`

### Architect review focus

- confirm this umbrella should be decomposed before implementation
- confirm which parts belong to metadata/data versus generic runtime

---

### 8.2 `#1511` Required-field validation umbrella

Issue: [#1511](https://github.com/pingcap-inc/MetaDrivenPlatform4AI/issues/1511)

### Why this is not Flow-first

The issue body itself points to frontend `MetadataRecordForm` validation.
Its `module/flow` label comes from affected surfaces such as Flow Builder
panels, not because the Flow engine is the right first repair target.

### Recommended handling

- route to frontend/form validation track
- keep only the Flow Builder UI pieces in the flow backlog
- do not let this issue compete with Flow substrate priorities

### Architect review focus

- confirm the issue should be de-scoped from the Flow-first repair wave

---

## 9. Recommended Execution Waves

### Wave 1: bounded correctness

- `#1792`

Goal:

- close live engine bug
- verify staging truth versus local/unit truth

### Wave 2: core substrate

- `#1456`
- `#1464`
- `#1465`

Goal:

- close the three named Flow substrate gaps already reflected in the updated
  Flow design overview

### Wave 3: migration bridge and data-model decision

- `#1469`

Goal:

- unblock near-term migration with a clearly temporary bridge
- force an explicit platform decision on computed-field semantics

### Wave 4: business consumers

- `#1539`
- Flow-related slice of `#1511`

Goal:

- consume the repaired substrate instead of shaping it prematurely

---

## 10. Review Questions For Architecture

These are not meant as rhetorical questions. They are the specific
confirmation items that should determine whether work proceeds as:

- point fix
- substrate implementation
- temporary bridge
- or deferred consumer rollout

These are the questions I would explicitly ask the architect to review:

1. Is `#1792` truly a bounded dispatcher/execution-boundary defect, or does it
   expose a deeper mismatch in the record-event pipeline?
2. For `#1456`, should formula results be persisted in interview state across
   Wait/resume, or re-evaluated on resume by policy?
3. For `#1464`, should scheduled paths use a dedicated scheduled-job table, or
   should they be modeled as a specialized FlowInterview lifecycle?
4. For `#1465`, what exact shared sender-resolution primitive should Flow use,
   and what semantic delta from the current ApprovalService helper must be
   declared explicitly?
5. For `#1469`, is Flow an acceptable tactical bridge for denormalized cache
   fields, what is the temporary semantic delta from Salesforce behavior, and
   what exit mechanism makes that bridge enforceably temporary?
6. Should `#1539` and `#1511` be formally reclassified as downstream consumers
   rather than first-wave Flow issues?

---

## 11. CLAUDE.md Alignment Notes

This plan was written against the repository's metadata-driven architecture
rules in [`CLAUDE.md`](../../../CLAUDE.md).

### 11.1 Where this plan is aligned

1. **Interpreter stays generic.**
   - The plan does not propose object-name branches such as
     `if objectName == "Lead"` inside generic Flow runtime code.
   - Issue `#1792` is framed as a suspected bounded event/dispatch defect,
     pending repro on current `main`, not as a Lead-specific special case.

2. **Metadata stays the authoring layer for business facts.**
   - The updated Flow overview and this remediation plan both treat Flow,
     standard actions, guards, defaults, and action visibility as metadata
     surfaces rather than business logic hardcoded in Go.
   - The recommended direction for `#1456`, `#1464`, and `#1465` extends
     generic runtime capabilities instead of embedding one tenant's flow logic
     into the binary.

3. **One fact, one SSoT, one read path.**
   - The plan explicitly separates:
     - Flow execution graph semantics
     - standard-action invocation contract semantics
   - This is meant to avoid parallel ownership of the same fact across Flow
     JSON, frontend literals, and Go branches.

4. **Umbrella business issues should consume substrate, not define it.**
   - `#1539` and `#1511` are intentionally classified as downstream consumers
     so that business rollout pressure does not push the Flow runtime into
     ad hoc design shortcuts.

### 11.2 Where this plan needs deliberate architectural scrutiny

1. **`#1469` denormalized formula-cache fields**
   - This is the highest-risk item relative to `CLAUDE.md`.
   - A small tactical bridge may be acceptable for migration, but it must not
     become a permanent second-class computation system hidden inside Flow.
   - If the bridge has no explicit exit strategy, it risks violating:
     - "one fact, one SSoT"
     - "legacy remediation belongs in data specs / durable platform model, not
       long-lived runtime special cases"

2. **`#1464` scheduled paths persistence model**
   - This plan no longer freezes a dedicated scheduled-job table as the default.
   - The current review posture is to start from `FlowInterview` reuse as the
     hypothesis to beat, because the runtime already has a durable wake-up
     primitive in `PausedUntil` plus claim/resume machinery.
   - A dedicated scheduled-job table is acceptable only if the design note names
     the concrete mechanism that `FlowInterview` cannot model cleanly, and why
     extending interview lifecycle/accounting is insufficient.

3. **`#1465` template rendering / sender resolution**
   - The plan assumes this should reuse the generic resolver and shared sender
     contract, not create a second mini-engine for email behavior.
   - Architect review should confirm the implementation path preserves a single
     read path for sender and resource resolution semantics.

### 11.3 Practical review lens from `CLAUDE.md`

For each issue in the plan, the architect review should ask:

1. Can an admin change the behavior through metadata, or does it still require
   a code change?
2. Does the proposal keep the L0 runtime blind to tenant/business instances?
3. Does the proposal reuse the existing platform primitive before inventing a
   new one?
4. Does the proposal introduce a second source of truth for a fact that
   Salesforce/NexusCRM metadata already models?

If any implementation direction fails one of those checks, the plan should be
considered out of alignment and revised before coding.

---

## 12. Suggested Next-Step Decision Pattern

Recommended post-review decision pattern:

1. **Approve and start immediately**
   - only for items whose architecture is now confirmed
2. **Approve investigation only**
   - when the architecture is probably right, but the failing layer still needs
     confirmation (`#1792`)
3. **Approve implementation prep but not coding**
   - when decomposition and internal interfaces can be prepared safely, but the
     final contract still needs a decision (`#1464`, `#1465`, `#1469`)
4. **Approve decomposition only**
   - for downstream umbrella consumers (`#1539`, `#1511`)

Using those four buckets should reduce the risk of treating “we have a good
direction” as “we have a frozen implementation contract”.

---

## 13. Action Plan After Architect Review

This section converts the classification above into a concrete execution plan.
The intent is to make two boundaries explicit:

- what we should do **now**
- what we should **not** lock into code until the architect confirms the
  contract

### 13.1 Start now

These items are safe to start immediately because they either reduce ambiguity
or do not commit us to the disputed design surface yet.

1. `#1792` repro + classification
   - local repro on current `origin/main`
   - staging repro confirmation against the current issue script
   - trace exact event path for:
     - direct update
     - convertLead update
     - post-save async/detached path
   - output:
     - a short root-cause note
     - final classification: bounded point fix vs structural pipeline issue

2. `#1456` implementation prep and coding
   - safe to proceed with validation / dependency / regression closure on top of
     the evaluator path already landed on `main`
   - safe to prepare contract tests for formula resources
   - safe to split PRs along validation / regression boundaries without
     reopening baseline evaluator plumbing unless a concrete failing case
     proves it is insufficient
   - output:
     - implementation PR(s)
     - formula contract test matrix

3. `#1539` / `#1511` decomposition only
   - split umbrella issue into child tracks
   - remove Flow-first pressure from business rollout items
   - output:
     - child issue breakdown
     - dependency map to Flow substrate capabilities

### 13.2 Prepare now, but wait before coding the core contract

These items are good candidates for design decomposition and interface prep,
but should not cross into full implementation before architect confirmation.

1. `#1464` scheduled paths
   - safe now:
     - write persistence options comparison
     - define required lifecycle states
     - draft retry/idempotency test cases
   - wait for confirmation:
     - scheduled-job table vs FlowInterview reuse
     - fire-time record semantics
     - kill-switch behavior
   - coding should start only after those three items are frozen

2. `#1465` template + sender contract
   - safe now:
     - document exact delta from current `ApprovalService` sender helper
     - draft resolver contract tests
     - identify what can be reused vs what must be extended
   - wait for confirmation:
     - shared sender primitive boundary
     - org-wide sender permission policy
     - polymorphic reference ownership
   - coding should start only after the sender contract is frozen

3. `#1469` tactical bridge
   - safe now:
     - field audit
     - candidate minimal bridge field list
     - durable follow-up issue definition
   - wait for confirmation:
     - whether Flow is allowed as the bridge carrier at all
     - bridge semantic choice
     - mandatory exit trigger
   - coding should start only after the bridge is explicitly approved as
     temporary and bounded

### 13.3 Discuss later, at implementation review time

These questions matter, but they do not need to block the current architecture
review if the higher-level contract is not yet frozen.

1. `#1456`
   - exact memoization implementation shape
   - detailed activation-error message format

2. `#1464`
   - support/debug UI shape for pending scheduled jobs
   - worker observability field layout

3. `#1465`
   - final HTML escaping implementation detail
   - exact unresolved-token error wording

4. `#1469`
   - cleanup sequencing once the durable model lands
   - whether removal is best done by data-spec only or data-spec + runtime guard

### 13.4 Recommended execution sequence

If the architect agrees with the current split, the recommended order is:

1. finish `#1792` repro and final classification
2. start `#1456` implementation
3. decompose `#1539` and `#1511` so they stop distorting substrate priorities
4. freeze `#1464` contract, then implement
5. freeze `#1465` contract, then implement
6. freeze `#1469` bridge scope and exit rule, then implement only the minimal
   temporary bridge if still needed

### 13.5 What should not happen

Until the architect confirms the pending boundaries, we should explicitly avoid:

1. treating `#1464` as a straightforward worker implementation task
2. reusing `ApprovalService` sender logic in `#1465` without declaring the
   semantic delta
3. turning `#1469` into an open-ended Flow-based denormalization mechanism
4. letting `#1539` or `#1511` define generic Flow runtime behavior

---

## 14. Broader Flow Issue Landscape

Beyond the first-wave 7 issues, the open `module/flow` backlog already forms a
smaller number of repeatable repair clusters. The goal here is **not** to lock
every child issue into a detailed mini-spec. The goal is to make sure the next
discussion with the architect is about a stable cluster map instead of
issue-by-issue noise.

This section is based on:

- [issue #1825](https://github.com/pingcap-inc/MetaDrivenPlatform4AI/issues/1825)
- [issue #1817](https://github.com/pingcap-inc/MetaDrivenPlatform4AI/issues/1817)
- the current open `module/flow` backlog as of 2026-04-26

Some issues intentionally appear in more than one cluster below. The cluster
map is a map of **repair surfaces**, not a mutually exclusive ownership tree.
For example, `#1469` is both:

- a computed-value design topic
- a migration-bridge / ownership topic

### 14.1 Cluster map

| Cluster | Representative issues | Current view | Discussion prompt / next design slice |
|---|---|---|---|
| A. Trigger dispatch / subscription / trigger-metadata write path | `#1792`, `#1789`, `#1788`, `#1782`, `#1351`, `#1745` | engine correctness + metadata persistence drift | confirm whether these are one shared trigger-pipeline diagnosis surface or multiple narrower bugs before freezing a repair contract |
| B. Filter / operator semantics | `#1968`, `#1780`, `#1801`, `#2052`, `#1760`, `#1292` | same evaluator family is still inconsistent across in-memory and SQL paths | decide whether one shared evaluator contract should own these semantics, then spin out a dedicated design slice with baseline/evidence/delta/verification |
| C. AfterSave execution-chain stability | `#1787`, `#1800`, `#1795` | mostly a hardening tail after the deadlock fix | treat as focused correctness hardening, not new architecture |
| D. Scheduled / async runtime | `#1464`, `#1790`, `#1394` | one strategic substrate gap plus small follow-up defects | keep `#1464` as the only frozen design slice in this family for now; treat the others as consumers/follow-ups until a broader async contract is separately reviewed |
| E. Resolver / cross-object path semantics | `#1743`, `#1754`, `#1751`, `#1472`, `#1466`, `#1607` | runtime can resolve more than Builder can author; some polymorphic rules still drift | determine whether these truly share one resolver contract before proposing a unified repair plan |
| F. Formula / computed-value semantics | `#1456`, `#1444`, `#2053`, `#1469` | same business expectation appears in Flow formulas, entry formulas, SObject formulas, and downgraded cache columns | use this as a topic map only; do not treat it as one implementation plan until layered ownership, deltas, and validation are separately frozen |
| G. Email / action contract | `#1465`, `#1392`, `#1393`, part of `#1539` | backend sender/template contract and Builder action UX are incomplete together | decide whether sender/template/runtime/UI should be one contract surface or multiple narrower follow-up slices |
| H. Record-operation substrate gaps | `#1474`, `#1471`, `#1470`, `changeOwner` gap called out in PR review | standard-action migration still depends on generic record-op capability parity | confirm the generic substrate inventory first, then write a dedicated parity design slice instead of treating this row as an approved solution |
| I. Data / tenant-overlay / migration bridge | `#1467`, `#1355`, `#1469` | some items are tenant-overlay ownership questions, not generic engine bugs | separate tenant-overlay ownership questions from temporary bridge pressure before any contract is frozen |
| J. Builder / Tooling / list / persistence UX | `#1381`, `#1405`, `#1356`, `#1383`, `#1311`, `#1312`, `#1231`, `#1232` | several P1s are authoring fidelity gaps rather than runtime gaps | keep these grouped for backlog visibility, but require a later UI/tooling design slice before treating them as one approved repair wave |
| K. Test / runnability / regression backlog | `#1817`, `#1825`, `#2044`, `#2043`, `#1313` | not substrate by itself, but required to stop regressions from hiding | tie each regression/design gap to a parent cluster; do not treat this row alone as a sufficient remediation contract |
| L. Downstream umbrella consumers | `#1539`, `#1511`, `#1518`, `#1522` | cross-module rollout issues that consume repaired substrate | decompose these into child issues after substrate contracts are frozen; this row is consumer triage, not an implementation design |

### 14.2 Practical split

For planning purposes, I would treat the full backlog as four bands:

1. **Immediate correctness**
   - A, B, C
2. **Core substrate**
   - D, E, F, G, H
3. **Migration / ownership cleanup**
   - I
4. **Authoring / audit / consumer layers**
   - J, K, L

This is the main change from the earlier draft: the first-wave 7 issues are
still the center of gravity, but they are now placed inside a broader map that
explains what the rest of the open Flow queue is actually asking for.

That broader map is intentionally a **triage view**, not a merged design
contract for every listed cluster.

---

## 15. Metadata-Driven Repair Guardrails

The broader Flow backlog cannot be repaired issue-by-issue without repeatedly
crossing the project red lines. The metadata-driven section of
[`CLAUDE.md`](../../../CLAUDE.md) gives the guardrails that should shape every
solution choice:

1. **Author decides layer**
   - tenant rules, object-specific behavior, and business field meaning should
     not be pushed into L0 Flow runtime code
2. **Interpreter is blind to instances**
   - no object-name / field-name / tenant-name branches inside generic Flow
     engines
3. **One fact, one SSoT, one read path**
   - evaluator semantics, sender semantics, and computed-value semantics should
     each converge to one contract, not separate Flow-only substitutes
4. **Exhaust reuse before inventing**
   - Flow should reuse SF-shaped metadata or an existing platform primitive
     before inventing a new special mechanism

### 15.1 Consequences for the current backlog

These principles materially change the recommended repair direction:

1. `#1469` and `#2053`
   - should not become two unrelated computation systems
   - we need one declared relationship between:
     - Flow formula resources
     - Flow entry-condition formulas
     - SObject formula fields
     - downgraded denormalized cache columns
   - this does **not** imply one Flow-owned implementation path; it implies one
     architecture-level model with explicit layered ownership
2. `#1607`
   - Builder drift is not just a UI bug bucket
   - if runtime supports nested refs but Builder cannot author or preserve
     them, we have effectively created two metadata contracts
3. `#1467` and `#1355`
   - tenant-specific objects/flows belong in tenant overlay ownership, not in
     generic platform packs or generic runtime branches
4. `#1474`, `#1471`, `#1470`, and the `changeOwner` gap
   - should be repaired as generic record-operation capability parity
   - they should not be solved by action-specific one-off branches

### 15.2 Wrong directions to avoid

1. fixing trigger issues by adding object-specific listener special cases
2. fixing email gaps by creating a Flow-only sender mini-contract unrelated to
   Approval/email substrate
3. fixing formula/cache issues by leaving multiple long-lived computation
   systems active at once
4. fixing Builder drift by silently narrowing frontend authoring to less than
   the backend contract

---

## 16. Proposed Multi-Phase Closure Plan

If the goal is to make the current Flow issue set **actually converge**, I
would plan for five phases rather than a single repair wave.

### 16.1 Phase 0: architecture confirmation + investigation package

Goal:

- collect enough evidence and option comparisons that architect review can
  freeze the disputed boundaries

Should complete in this phase:

- `#1792` repro + final classification
- option comparisons for `#1464`, `#1465`, `#1469`
- broader cluster map and phase ownership
- first-wave acceptance criteria and PR split drafts

### 16.2 Phase 1: immediate correctness

Goal:

- close live engine correctness defects before adding more substrate surface

Main items:

- Cluster A trigger correctness
- Cluster B operator/filter correctness
- Cluster C AfterSave hardening

Representative issues:

- `#1792`, `#1782`, `#1780`, `#1801`, `#1968`, `#2052`

### 16.3 Phase 2: core Flow substrate

Goal:

- close the missing generic capabilities that multiple business flows and
  standard actions are waiting on

Main items:

- Cluster D scheduled/async runtime
- Cluster E resolver parity
- Cluster F formula/computed-value substrate
- Cluster G email/action contract
- Cluster H record-operation parity

Representative issues:

- `#1456`, `#1464`, `#1465`, `#1444`, `#1466`, `#1474`, `#1471`, `#1470`,
  `#2053`

### 16.4 Phase 3: migration bridge and ownership cleanup

Goal:

- handle migration-only pressure without baking tenant or temporary semantics
  into the permanent platform

Main items:

- Cluster I

Representative issues:

- `#1469`, `#1467`, `#1355`

### 16.5 Phase 4: Builder / Tooling / runnability closure

Goal:

- make the authored metadata surface actually match the repaired backend
  contract

Main items:

- Cluster J
- Cluster K

Representative issues:

- `#1607`, `#1381`, `#1405`, `#1356`, `#1311`, `#1312`, `#1231`, `#1232`,
  `#1817`, `#2044`, `#1313`

### 16.6 Phase 5: downstream consumer rollout

Goal:

- let business umbrellas consume the repaired substrate instead of defining it

Main items:

- Cluster L

Representative issues:

- `#1539`, `#1511`, `#1518`, `#1522`

---

## 17. Architect Discussion Prompts By Cluster (Non-Contract)

This section is intentionally **not** an execution-ready design contract.
It is a backlog-level architect discussion aid for the broader cluster map.

Use it to review:

- whether the grouping itself is sensible
- which clusters likely deserve their own dedicated design slice next
- which topics are substrate versus consumer follow-up

Do **not** use it as approval to implement any cluster-wide repair shape yet.
For any cluster outside the 7 first-wave issues, implementation should wait for
a dedicated follow-up design slice that answers the full design-doc gate:

- Salesforce baseline
- candidate paths
- repo evidence
- declared NexusCRM delta + justification
- next-tenant impact
- verification plan

### 17.1 Cluster A: trigger dispatch / trigger-metadata write path

Discussion prompt:

- treat `#1792`, `#1789`, `#1788`, `#1782`, `#1351`, and `#1745` as one
  trigger-pipeline family until disproven
- repair shared listener registration and FlowDefinition write-path drift before
  making per-flow conclusions

Why:

- multiple issues point to the same boundary: trigger metadata shape versus
  actual dispatchability

### 17.2 Cluster B: filter / operator semantics

Discussion prompt:

- unify in-memory condition evaluation and SQL-builder condition evaluation
- explicitly close `false`/`blank`/`null` parity bugs together

Why:

- this is a textbook `one fact, one read path` area; split fixes will regress

### 17.3 Cluster D/E/F/G/H: substrate family

Discussion prompt:

- design and implement these as a coordinated substrate wave, not scattered
  feature tickets

Specific shape:

1. formulas / computed values
   - align `#1456`, `#1444`, `#2053`, and `#1469` under one declared
     computed-value design topic
   - keep layered ownership explicit:
     - Flow formula resources stay Flow-runtime substrate
     - SObject formula fields stay records/metadata substrate
     - downgraded cache fields, if temporarily bridged, stay explicitly outside
       the durable Flow contract
2. async runtime
   - freeze scheduled-path durable semantics before worker/UI work
3. resolver parity
   - freeze generic nested / polymorphic / prior-value semantics before Builder
     parity work
4. action/email contract
   - freeze sender/template contract before UI completion
5. record-op parity
   - treat missing record-operation capabilities as generic engine work that
     unblocks standard-action migration

### 17.4 Cluster I: migration bridge / tenant ownership

Discussion prompt:

- split platform bugs from tenant-overlay ownership from temporary bridge needs

Specific shape:

1. `#1467` / `#1355`
   - route to tenant-overlay ownership discussion
2. `#1469`
   - allow only a minimal bridge with named fields + semantic delta + exit
     trigger

### 17.5 Cluster J/K/L: authoring, audit, consumers

Discussion prompt:

- Builder fidelity and audit issues should follow behind the substrate contract,
  but they should still be grouped into their own explicit wave
- business umbrellas should be decomposed now, not when substrate coding starts

---

## 18. Summary

My current split is:

- **Suspected single-point fix, gated on repro**
  - `#1792`

- **Structural design**
  - `#1456`
  - `#1464`
  - `#1465`
  - `#1469`

- **Umbrella / downstream consumer**
  - `#1539`
  - `#1511`

And my current recommended order is:

1. `#1792`
2. `#1456`
3. `#1464`
4. `#1465`
5. `#1469`
6. `#1539`
7. `#1511`

This ordering optimizes for:

- closing live correctness bugs first
- stabilizing shared substrate before business-flow rollout
- preventing umbrella business issues from driving engine design prematurely
- keeping the broader Flow backlog inside one metadata-driven repair map rather
  than a set of disconnected issue-by-issue fixes

Important boundary:

- the 7 named first-wave issues above are the only parts of this document that
  currently claim detailed design coverage
- clusters A-L are triage/grouping guidance only and still need separate
  design-evidence slices before they become implementation contracts
