11 KiB
Conditional Logic: Gap Analysis & Design
This document captures the structural differences between Adobe Sign's and DocuSign's
conditional field models, which gaps are solvable in the migrator, and the design of
proposed solutions. It complements field-mapping.md (current-state reference) and
IMPLEMENTATION-PLAN.md (feature history).
Background: The Two Models
Adobe Sign supports full conditional logic per field:
conditionalAction.predicates[]— one or more{fieldName, operator, value}tuplesanyOrAll— ANY (OR) or ALL (AND) combining semanticsaction— SHOW or HIDE the fieldoperator— EQUALS, NOT_EQUALS, GT, LT, CONTAINS, etc.- The trigger field can belong to any recipient; cross-recipient conditions are valid
DocuSign supports a single, simple reveal condition per tab:
conditionalParentLabel— thetabLabelorgroupNameof the trigger tabconditionalParentValue— the exact string value that reveals the tab- The trigger tab must be a
listTab,radioGroupTab, orcheckboxTab - The trigger and the dependent tab must belong to the same recipient
- Only one condition per tab, always EQUALS, always a SHOW (reveal)
This is the deepest structural asymmetry in the migration. Every gap below flows from the gap between these two models.
Gap Catalog
Gap 1 — HIDE action
Adobe: action: HIDE — field is visible by default and hides when the condition is met.
DocuSign: No equivalent. DocuSign only supports revealing a tab that starts hidden.
Current behavior: Condition dropped; field always visible. HIDE_ACTION issue emitted.
Gap 2 — NOT_EQUALS and other operators
Adobe: Supports NOT_EQUALS, GT, LT, CONTAINS, etc.
DocuSign: Only EQUALS is supported.
Current behavior: Condition dropped; field always visible. UNSUPPORTED_OPERATOR issue emitted.
The most common real-world case is NOT_EQUALS "" (show this field if the user
entered anything in another field). This is doubly broken in DocuSign:
- NOT_EQUALS has no equivalent
- Text fields can't be conditional parents at all (see Gap 5)
Gap 3 — Cross-recipient conditionals
Adobe: Field B can show/hide based on the value of Field A even if A and B
belong to different recipients.
DocuSign: conditionalParentLabel resolves only within the same recipient's tab
set. The API silently ignores or rejects cross-recipient references.
Current behavior: Condition dropped. CROSS_RECIPIENT_CONDITIONAL issue emitted.
Gap 4 — Multi-predicate ANY (OR) logic
Adobe: anyOrAll: ANY with multiple predicates — show if condition 1 OR condition 2 OR …
DocuSign: One conditionalParentValue per tab — no native OR.
Current behavior: Only the first EQUALS predicate is mapped; rest are dropped.
MULTI_PREDICATE issue emitted.
Gap 5 — Invalid conditional parent tab types
Adobe: Any field can be a conditional trigger — text fields, signature fields, anything.
DocuSign: Only listTabs, radioGroupTabs, and checkboxTabs may be conditional
parents. All other types cause CONDITIONALTAB_HAS_INVALID_PARENT (400).
Current behavior: Strip pass removes conditions referencing invalid parent types.
INVALID_PARENT_TAB issue emitted.
Gap 6 — Multi-predicate ALL (AND) logic
Adobe: anyOrAll: ALL — show only if ALL conditions are simultaneously true.
DocuSign: No AND logic at the template conditional level.
Current behavior: Only the first EQUALS predicate is mapped. MULTI_PREDICATE issue emitted.
The DocuSign "Flags" Technique
DocuSign's "Building Advanced Templates" guide describes using hidden intermediate tabs ("flags") to work around the platform's single-parent conditional model. The pattern:
- Create a hidden
checkboxTaborlistTab— the "flag" — placed out of the visible form area or givenlocked: true, selected: false. - Make the flag conditionally revealed by one condition (the flag itself is shown when condition A is true).
- Make the dependent field conditionally revealed when the flag is in a specific state.
This creates two-level conditional depth. However, DocuSign tabs don't auto-set their own value — a checkbox flag only "activates" when the signer checks it, or when the sender pre-fills it before sending. This limits the technique to two scenarios:
Scenario A — Sender-prefill flags: The sender manually checks/sets flags before routing the envelope, making explicit business logic decisions that the template cannot express automatically. Useful for bespoke workflows but not for automated migration.
Scenario B — Checkbox-group section selectors: For OR-style logic driven by a single dropdown, radio group, or checkbox, the flag technique is not needed — the multi-copy approach (Gap 4 solution below) handles this cleanly.
Bottom line: The flag technique is a UI/manual-workflow tool, not an automated migration output. It doesn't solve AND logic or cross-recipient conditions without human intervention at sending time.
Solvable Gaps: Proposed Designs
Solution A — ANY multi-predicate fan-out (addresses Gap 4, partially Gap 2)
Scope: When anyOrAll: ANY and all predicates share the same parent field and all
use EQUALS, the OR logic can be emitted as one copy of the dependent tab per
predicate value, all at the same coordinates with the same tabLabel.
At signing time, DocuSign shows exactly the copies whose condition is satisfied.
Because the copies share a tabLabel, their values sync — the signer fills one and
DocuSign treats them as the same logical field.
Before (current output — only first predicate mapped):
{ "tabLabel": "Notes", "conditionalParentLabel": "Category",
"conditionalParentValue": "Option A" }
After (fan-out):
{ "tabLabel": "Notes", "conditionalParentLabel": "Category",
"conditionalParentValue": "Option A" },
{ "tabLabel": "Notes", "conditionalParentLabel": "Category",
"conditionalParentValue": "Option B" }
NOT_EQUALS expansion (Gap 2, dropdown parents only): When the operator is
NOT_EQUALS and the parent is a listTab, look up the parent field's option list and
compute the complement — emit one copy per remaining value. This covers the common
"show unless user picked X" pattern.
Limitations:
- Only works when all predicates reference the same parent field
- Mixed-parent ANY (field A = x OR field B = y) is still unsupported
- NOT_EQUALS expansion only works for
listTabparents with a finite option set - Text field parents remain invalid regardless of operator (Gap 5)
New issue codes proposed:
MULTI_PREDICATE_EXPANDED(info) — OR logic successfully fanned outNOT_EQUALS_EXPANDED(info) — NOT_EQUALS resolved via complement enumerationNOT_EQUALS_UNEXPANDABLE(warning) — NOT_EQUALS on a non-list parent; condition dropped
Solution B — Richer guidance messages for unsolvable gaps
All currently unsolvable gaps emit a generic "condition dropped" message. Each gap warrants a specific, actionable message explaining the constraint and what to do manually.
| Gap | Improved guidance |
|---|---|
HIDE_ACTION |
"Restructure as a SHOW condition: start the field hidden (remove it from the base layout) and show it when the inverse condition is met. If the trigger is a dropdown, this requires listing all values that should reveal the field." |
CROSS_RECIPIENT_CONDITIONAL |
"Add a prefill recipient (routing order 0) that holds the controlling field. Downstream signers' conditional fields can then reference the prefill tab. The sender sets the value before routing." |
INVALID_PARENT_TAB (text parent) |
"DocuSign requires a dropdown, radio group, or checkbox as the condition trigger. Replace the text field trigger with a dropdown containing expected values, then the condition can be mapped." |
MULTI_PREDICATE (mixed parents) |
"DocuSign supports one condition per field. Split this field into two separate positioned fields, each conditional on one predicate." |
Unsolvable Gaps (Fundamental Limits of DocuSign Templates)
These gaps cannot be addressed at the template layer regardless of technique:
| Gap | Why |
|---|---|
| HIDE action (general) | DocuSign has no "start visible, hide when X" model. Inversion via complement enumeration only works for dropdown triggers with finite option sets. |
| Text field as conditional parent | DocuSign's API flatly rejects any tab type other than listTabs, radioGroupTabs, checkboxTabs as a parent — this is a server-side constraint, not a schema quirk. |
| AND logic (multi-predicate ALL) | DocuSign template conditionals have no AND. The flag chaining technique requires a human to set intermediate flags at sending time, making it unsuitable for automated migration output. |
| Mixed-parent ANY | "Show if field A = x OR field B = y" requires two independent conditions on the same tab, which the single-parent model cannot express. |
| Cross-recipient without prefill restructure | True cross-recipient logic (signer 2's visibility driven by signer 1's choice) requires restructuring the recipient list to add a prefill signer — a structural change, not a tab-level fix. |
The right platform for these cases is DocuSign Maestro (Workflow automation), which supports proper conditional branching, cross-step data references, and decision gateways. Templates with significant AND logic or cross-recipient conditionals should be flagged as Maestro candidates in the migration report.
Proposed Implementation Phases
Phase 24 — NOT_EQUALS expansion for dropdown parents
- Detect
operator: NOT_EQUALSwhere parent field is alistTab - Look up parent's
hiddenOptions/visibleOptionsfrom the Adobe source fields - Compute complement set (all options except the excluded value)
- Emit one tab copy per remaining option with
conditionalParentValue = option - Emit
NOT_EQUALS_EXPANDEDinfo issue - Emit
NOT_EQUALS_UNEXPANDABLEwarning for non-list parents (unchanged drop behavior) - Tests: unit tests for complement computation; regression snapshots updated
Phase 25 — ANY multi-predicate fan-out
- Detect
anyOrAll: ANY, multiple predicates, all referencing the same parent field, all usingEQUALS - Emit one tab copy per predicate value at the same coordinates with the same
tabLabel - Emit
MULTI_PREDICATE_EXPANDEDinfo issue - Cases with mixed parents or non-EQUALS operators keep
MULTI_PREDICATEwarning - Tests: unit tests covering fan-out; mixed-parent case stays as warning
Phase 26 — Richer issue guidance text
- Update
HIDE_ACTION,CROSS_RECIPIENT_CONDITIONAL,INVALID_PARENT_TAB, andMULTI_PREDICATEmessage strings to include specific manual fix instructions - No behavioral change — UI display only
- Tests: update any tests that assert on exact message strings
Phase 27 — Maestro escalation advisory
- Add template-level
MAESTRO_RECOMMENDEDadvisory (distinct from per-field issues) when a template contains unresolvable AND logic, cross-recipient conditionals, or HIDE actions that affect more than N fields (threshold TBD) - Surface in the Issues tab of the template detail view
- No code generation — guidance only
Created: 2026-05-14. Companion documents: field-mapping.md (current-state reference),
docs/IMPLEMENTATION-PLAN.md (feature history), tests/EDGE-CASES.md (known edge cases).