# Active Workarounds Registry

This file tracks **L2 (or L1) workarounds that exist only because an upstream
L0/L1 bug is not yet fixed**. Every entry must be revisited when the upstream
fix lands, so the workaround can be reverted (or, after deliberate evaluation,
promoted to a permanent design choice).

## Why this exists

Workarounds tend to outlive the bugs that justified them. Years later, no one
remembers why a permission was granted, why a runtime DDL patch is in place,
or why a field has a defensive default. The result is silent technical and
security debt.

This registry is the single source of truth for "what temporary fixes are
currently live, and when can they go away."

## Rules

1. **Add an entry as part of any PR that introduces a workaround for an
   upstream bug.** The PR template prompts for this; CI/review should enforce
   it.
2. **Every entry must list a concrete revert criterion**, not a vague
   "upstream is fixed." Specify *how to verify* the upstream fix has actually
   landed in the relevant deployed environment.
3. **Every entry must have a named owner** — not a team. The owner is
   responsible for noticing when the revert criterion is met and driving the
   revert through the normal deploy/change process.
4. **Status transitions are explicit**: `Active` → `Revertable` (upstream
   landed, revert pending) → `Reverted` (verified gone in prod) → archived
   (move to the bottom-of-file table after one monthly review cycle).
5. **Permission-relaxing workarounds are highest priority to revert.** They
   are persistent security debt until removed.
6. **Do not auto-revert.** Mechanism here tracks and reminds; revert is always
   a human decision via the normal change process.

## Monthly review

Platform lead reviews this file every month:
- Move entries whose upstream is `closed` and prod has been redeployed since
  the close → `Revertable`. Add to next sprint's backlog.
- Entries where upstream has been open > 3 months → evaluate: keep pushing
  upstream, or formally promote the workaround to a permanent decision and
  remove it from this registry.
- Reassign owners that have left or changed roles.

---

## Active entries

| ID | Created | Where / What | Upstream | Revert Criterion | Owner | Status |
|----|---------|--------------|----------|------------------|-------|--------|
| WA-001 | 2026-05-29 | L2 pack `packs/Salesforce-PingCAP-L2/permissions/*` — grant `PermissionsViewAllRecords = 1` on `FlowDefinition` and `Flow` to 11 non-admin profiles (Standard User, Sales, Pre-Sales, Marketing, Finance, SDR, Alliance & Channel, Demand Gen Manager, Automated Process, PM, Tech Support). See pingcap-inc/nexuscrm-pingcap-pack#2119 for details. **2026-06-25 — generalized:** the 11-name allow-list still left 38 of 50 profile-owned permsets at `Read=1 / ViewAll=0` (reported: DM, Sales Ops, System Administrator (SF imported); also Legal, Management, Contract Manager, Demand Gen, etc.). Patch bundle `docs/migration/patch-bundles/20260625_flow_visibility_all_profiles` now grants `ViewAllRecords` on `Flow`+`FlowDefinition` to **all** profile-owned permsets, set-based (`IsOwnedByProfile=1`, no name list), superseding the scope of the 20260529 bundle. NB the live delivery mechanism is the patch bundle, not pack `permissions/*` (profile-owned `ObjectPermissions` are not tracked in pack source). | pingcap-inc/NexusCRM#1553 (L0 RLS treats pack-owned `_System_FlowDefinition` rows as regular records) | (1) Upstream #1553 closed AND merged commit present in deployed prod backend binary; (2) Manual verification: log in as a Sales-profile user without the workaround grant, click any standard pack flow trigger (e.g. activity-timeline "Log a Call") → succeeds without "Flow not found or not active" error. | sydpz | Active |
| WA-002 | 2026-05-29 | Runtime DDL hot patch on prod `v_opportunity` view: replaced 7 mis-bound `j_opportunities_partner_name.<account-derived-field>` references with `j_account.<same-field>` (Region__c, Vertical__c, Industry, Account_Name_Original__c, FY22_IB__c, Lighthouse__c, Rating). See pingcap-inc/nexuscrm-pingcap-pack#2112. **NOT in pack source.** Will be overwritten on next `v_opportunity` rebuild. | (no upstream issue filed yet — staging backend already fixes the formula view builder's multi-`ReferenceTo`-Account join-disambiguation; prod just needs to deploy the newer backend version) | (1) Prod backend version aligned to staging's, AND (2) `v_opportunity` rebuilt from current backend → re-query DDL: `SHOW CREATE VIEW v_opportunity` no longer references `j_opportunities_partner_name` for any Account-derived field. | sydpz | Active |
| WA-003 | 2026-05-29 | L2 pack `packs/Salesforce-PingCAP-L2/objects/Credits__c.json` snapshot fields (`Account_Name__c`, `Opportunity_Name__c` — and any future snapshot string field that AE should see prefilled on the Create form) keep `createable: true` so the entry-point ui_action prefill + `Credits_Prefill_Snapshot_Fields` before-save Flow can write them. They cannot be authored as `createable: true, displayAsReadonlyOnCreate: true` because the pack format has no such flag — the layout's `editableForNew` is unconditionally derived from schema `createable` in upstream `primitives.go:401`. Net effect: AE sees an editable input on the Create form even though any value they type is silently overwritten by the before-save Flow (`Credits_Prefill_Snapshot_Fields.flow.json` uses `operator: Assign`). Confusing UX, but functionally safe (Flow guarantees the snapshot value). See pingcap-inc/nexuscrm-pingcap-pack#2055 for the original demo where this surfaced. | pingcap-inc/NexusCRM#1571 (Layout item `behavior: Readonly` not honored — Salesforce v63 parity gap) | (1) Upstream #1571 closed AND merged commit present in deployed backend binary; (2) Pack layout updated to declare `behavior: Readonly` (or equivalent) on the snapshot fields; (3) Manual verification: open New Credits form in browser → snapshot fields render as readonly display (not editable input). | jieni-droid | Active |
| WA-004 | 2026-05-29 | Phase 1 Credits MVP has no push notification when a Credits record reaches `Credit_Lifecycle__c = 'Active'` (post-approval, awaiting Cloud-side provisioning by Sales Ops). Sales Ops must discover these via a saved list view on `Credit_Lifecycle__c = 'Active'` and check daily per ops handbook procedure, then manually flip to `Provisioned` after loading credits on the Cloud Org. See proposal §6 Phase 1 Sales Ops discovery mechanism and §13 launch criterion (rolling 4-week median time-in-Active < 3 business days; zero records > 7 days without explicit hold). Volume estimate ~80-100/year ≈ ~2-3/week, manageable as daily check; relies on Sales Ops discipline rather than push. | pingcap-inc/NexusCRM#930 (SendNotification Flow action type) **AND** the Cloud-billing CallWebhook Phase 2/3 integration (no upstream issue — billing-team contract pending) | (1) Upstream NX#930 closed AND merged commit present in deployed backend binary; (2) The Cloud-billing CallWebhook Flow lands (auto-stamping `Provisioned` on Cloud-side load completion); (3) A push-notification Flow is added that fires when `Lifecycle='Active'` and ops latency exceeds threshold, so Sales Ops gets pinged instead of having to poll a list view. | jieni-droid | Active |
| WA-005 | 2026-05-29 | Validation Rule `PingCAP_Contract_Entity_EMEA_only` on `Opportunity` object temporarily disabled in prod. This rule enforces that EMEA Opportunities must carry a valid EMEA contract entity value; disabling it unblocks Opportunity creation for all users while EMEA contract entity data is not yet fully configured. **Must be re-enabled once the root cause is resolved.** | (no upstream issue yet — L2 pack validation rule too strict for current data state; EMEA contract entity picklist values and assignment workflow not fully seeded in prod) | (1) EMEA contract entity picklist values fully seeded in prod AND (2) assignment workflow/defaulting logic confirmed working — verified by creating an EMEA Opportunity end-to-end without hitting the validation error; (3) re-enable the rule in `packs/Salesforce-PingCAP-L2` and redeploy pack. | sydpz | Active |
| WA-006 | 2026-08-19 | Patch bundle `docs/migration/patch-bundles/20260819_task_status_open_and_lead_relate_flow` — one-time stopped D3 pre-Catalog recovery for a retained clone. The historical path is retained, but the bundle no longer repairs or verifies `Task.Status`: current Catalog DDL reconciliation owns that migration. For the exact nine issue #5139 `salesforce-crm-standard` FlowDefinitions, the SQL detaches only the reviewed custom active pointer and clears `IsCustomized`; the immediately following Catalog reconcile restores the shipped standard Flow behavior according to each Flow's authored Active/Draft status. `Deploy to Test` does not accept or replay this bundle. | `IsCustomized = 1` and a custom active pointer intentionally preserve administrator Flow behavior instead of standard-pack reconciliation | (1) L0 exposes a reviewed recovery operation for detached pack-owned Flows; (2) staging and production no longer contain the retained clone shape; (3) delete the bundle. | wshwsh12 | Active |

## Reverted entries (archive)

| ID | Created | Reverted | Notes |
|----|---------|----------|-------|
| _(none yet)_ | | | |

## How to add a new entry

1. Pick the next `WA-NNN` ID (zero-padded, monotonically increasing).
2. Fill in **Created** (today), **Where / What** (be specific: file paths, DDL,
   permission grants — enough that someone six months later can find what to
   undo), **Upstream** (issue link or explanation if no issue exists),
   **Revert Criterion** (concrete and verifiable), **Owner** (your GitHub
   handle or an explicit teammate), **Status** (start as `Active`).
3. If your workaround is in code, also add an inline marker comment near it:
   `// WORKAROUND-WA-NNN: revert when <upstream> lands` — so the code and this
   registry can be kept in sync.
4. Reference the WA ID in the body of any related issue.
