# Revisit triggers

A consolidated index of v1 design decisions that were closed with an
explicit condition under which they should be reopened. Each row names
the decision, the chosen v1 position, the trigger (the observation in
practice that would justify reopening), and the source where the
analysis lives.

This is a living index. When a decision is recorded with a deferred
alternative and a "trigger to revisit" clause, add a row here so the
condition is discoverable without reading every §8.x subsection or
decision record.

## Cross-cutting triggers

Two observations would justify reopening many of the rows below at
once, not just one. They sit above the per-decision table because
they are about the IR's fitness for the populations §1.1 prioritizes,
not about any single design choice:

1. **DSL cannot lower cleanly to the IR.** The IR is designed as a
   compile target (§1.1.2 codegen as primary writer, §1.2 verbose by
   design). If a DSL repeatedly cannot lower a common construct
   without faking IR shapes, side tables, or post-emission rewrites,
   the IR is failing its primary writer. The reopen is not "fix this
   one row"; it is "audit which rows are forcing the friction."
   Decisions most likely to come up: §8.15 hide-by-default `bind`,
   §8.17 pure SSA per namespace, §8.5 centralized `iterateState`,
   §8.16 task schema source. The audit may also surface a missing
   post-v1 mechanism (e.g., edge-scoped bind, block scope) that
   would close the gap additively.
2. **Engine performance suffers because of the lowering.** The IR's
   verbose-by-design tax assumes the engine pays no runtime cost for
   it (validation cost is one-time at load; runtime walks the
   compiled form). If profiling shows the lowering itself is the
   bottleneck (e.g., per-reference namespace dispatch, snapshot
   construction at every iteration boundary, schema re-validation hot in the
   inner loop), then v1 is taxing the dominant population. The
   reopen targets whichever rows the profiler points at; candidates
   include §8.1 type encoding, §8.3 branch model, §8.16 schema
   restatement, and the snapshot-read rule in §3.7.1.

Either trigger reopens decisions in clusters. The per-decision rows
below are still the correct catalog for narrow reopenings driven by
their specific triggers.

| #   | Topic                                                                | v1 position                                                                                                                                           | Trigger to revisit                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | Source                                                                                                                                                                                                                        |
| --- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |   | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1   | Type-system encoding (JSON Schema vs. compact custom IR)             | JSON Schema everywhere                                                                                                                                | IR size or author friction at scale becomes a real problem. Then a compact custom type IR (Option C) can be introduced as an alternative encoding that lowers to JSON Schema for runtime validation. Additive only.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | [ir-v0.1.md §8.1 notes](ir-v0.1.md) (post-v1 note 2)                                                                                                                                                                          |
| 2   | Branch model (discriminant switch vs. predicate `if/else`)           | Discriminant switch with required `default`; arms are `WorkflowScope`s ([decision 0010](decisions/0010-finish-workflow-scope-unification.md))         | Profiling shows per-decision task dispatch is a hot path (e.g., very tight branches inside large loops). A restricted predicate form (Alt A) may be reintroduced as an additive performance escape hatch, with its own P5 review. (The arm-as-scope shape introduced by 0010 does not change this trigger; it relates only to whether arms carry their own data flow.)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | [ir-v0.1.md §8.3](ir-v0.1.md) (post-v1 note); [decisions/0010-finish-workflow-scope-unification.md](decisions/0010-finish-workflow-scope-unification.md)                                                                      |
| 3   | Default-branch requirement (always required vs. enum-exhaustive)     | `default` always required                                                                                                                             | Enum-based exhaustiveness becomes trusted enough that the default can be relaxed for enum-typed selectors only.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | [ir-v0.1.md §8.3 Alt B](ir-v0.1.md) and §10 item 4                                                                                                                                                                            |
| 4   | Handler reuse (per-trigger vs. shared)                               | Exactly one trigger per handler                                                                                                                       | Patterns demand a single handler reachable from multiple triggers in **different scopes** (P4 scenario 35); same-scope multi-node coverage is addressed by post-v1 block scope, not by sharing. Shared handlers with intersection-of-dominators semantics (Alt A) become the natural extension.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | [ir-v0.1.md §8.7](ir-v0.1.md), [§8.11](ir-v0.1.md), [future/block-scope.md](future/block-scope.md), and [§10 handler-reuse row](ir-v0.1.md)                                                                                   |
| 5   | IR format (JSON vs. YAML vs. typed IR)                               | JSON                                                                                                                                                  | Authoring friction makes YAML or a typed surface compelling. YAML can land as authoring sugar without changing the IR; a typed IR would be a separate decision.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | [ir-v0.1.md §8.14](ir-v0.1.md) and [§10 IR-encoding row](ir-v0.1.md)                                                                                                                                                          |
| 6   | Task schema source of truth (omission-as-sugar)                      | IR is restatement-or-narrowing of the task envelope; schemas are required on nodes                                                                    | IR size becomes a pain point: most nodes restate their task's schemas verbatim and no DSL absorbs the cost. Option 3 (loader-expanded omission sugar) is the pressure-relief valve and reuses the chosen drift check unchanged.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | [decisions/0003-task-schema-source.md](decisions/0003-task-schema-source.md) ("Triggers to revisit Option 3"); [ir-v0.1.md §8.16 Alt C](ir-v0.1.md)                                                                           |
| 7   | Codegen coverage of IR shapes                                        | The IR carries shapes only the LLM-direct fallback or hand-author can reach                                                                           | Codegen coverage stays well below 100 % of IR shapes for an extended period. Then the uncovered shapes are paying IR-design cost (validator rules, engine paths, conformance) only for the fallback. Candidate responses: shrink the IR to what the DSL actually targets, or invest in DSL coverage so the gap closes.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | [ir-v0.1.md §1.1.2](ir-v0.1.md) (codegen as mechanical writer)                                                                                                                                                                |
| 8   | Static task registry (engine load time)                              | Registry is static across a single engine load; §4.1 pass 3 runs at load and rules out `TaskNotFound` / `TaskContractDrift` before execution          | A real need emerges to mutate the task set under a running engine (hot-reload of task implementations, multi-tenant registries that revoke tasks, plug-in style task addition). At that point the runtime failure class deferred from v1 needs a defined routing (`onError`? whole-workflow abort? pinned task version?), and the decision pulls in versioning and resume concerns also deferred from v1.                                                                                                                                                                                                                                                                                                                                                                                                                                                             | [ir-v0.1.md §2.2 "Dynamic task registry"](ir-v0.1.md), [§4.1 pass 3](ir-v0.1.md), [§5.7 MUST 7](ir-v0.1.md)                                                                                                                   |
| 9   | Pure SSA per namespace                                               | Every `$from` namespace is single-assignment within its frame; no in-place mutation; new frames re-bind names                                         | Foundational; reopening is a v2 question. If real workloads are mostly accumulator-shaped, or a declared parallelism construct needs more than per-frame SSA gives, or checkpointing wants a different frame granularity, or DSL lowering of mutable closures becomes hostile under the verbosity tax. The design move on reopen is **scope-narrowing** (introduce a new non-SSA namespace; leave the existing namespaces SSA), not relaxing SSA across the board: the latter would cascade into every §8 decision that depended on it. This move is the variance lens applied (IR §1.3 / §10): a different behavioral rule earns its own concept rather than being absorbed into an existing one.                                                                                                                                                                    | [decisions/0004-pure-ssa.md §9](decisions/0004-pure-ssa.md); [ir-v0.1.md §8.17](ir-v0.1.md)                                                                                                                                   |
| 10  | `$literal` escape and `$`-prefix reservation (template model)        | All `$`-prefixed object keys at template subtree roots are reserved; v1 recognizes `$from` and `$literal`; `$literal` returns its argument verbatim   | After five additional decisions beyond 0007, if no second engine-recognized template-position key (beyond `$from` and `$literal`) has been proposed **and** no scenario has surfaced a literal-`$from` collision requiring `$literal`, revisit whether the `$`-prefix reservation and `$literal` are earning their keep. The §1.3.1 (minimization) case for retreating to G-K1.b (reserve only `$from`, no `$literal`, no prefix reservation) gets stronger with each empty interval. The design move on retreat is **narrowing** (drop `$literal` and the open prefix; keep `$from` as the sole reserved key), not widening.                                                                                                                                                                                                                                         | [decisions/0007-value-construction-in-references.md §4 G-K1](decisions/0007-value-construction-in-references.md); [ir-v0.1.md §3.4](ir-v0.1.md)                                                                               |
| 11  | No expressions in the IR (standard-library tasks only)               | All computation goes through registered tasks; the IR has no expression sublanguage; the DSL lowers inline expressions to standard-library task nodes | A scenario surfaces a computation that (a) cannot be expressed as a standard-library task, or (b) the standard-library task pattern produces pathological node counts (>10 task nodes for a single conceptual computation), or (c) string interpolation is needed at >3 sites in a single workflow and a `string.concat` task is inadequate. Likeliest path: string interpolation for error messages or display values. Minimal response: `$expr` as a template-position key, string-typed, pure-functional, no arithmetic; extend only if arithmetic is independently forced. **Coupled decision:** if this row triggers, [decision 0008](decisions/0008-discriminant-key-encoding.md) (string-only discriminants) should be revisited together - `bool.toLabel` exists because the IR has no expressions, and predicate branches become natural once `$expr` lands. | [decisions/0006-no-expressions-in-ir.md](decisions/0006-no-expressions-in-ir.md); [decisions/0008-discriminant-key-encoding.md](decisions/0008-discriminant-key-encoding.md); [ir-v0.1.md §1.4, §3.4, §3.6, §8.3](ir-v0.1.md) |
| 12  | DSL surface: shorthand IR (Option D) as complement to imperative DSL | Imperative TS-like DSL (Option A) is the primary authoring surface; shorthand IR is deferred                                                          | Adopt shorthand IR if any two of: (a) quick-edit friction - authors find the full DSL compile round-trip slower than editing IR directly, but raw IR is too error-prone; (b) bootstrap gap - the DSL compiler is not yet available but authors need to write workflows now; (c) LLM IR-direct fallback (W2) is actively used and its error rate is dominated by schema restatement and `$from` verbosity. Shorthand IR occupies the space between raw IR and full DSL: a convenience layer for quick edits and bootstrap, not a replacement for the imperative DSL.                                                                                                                                                                                                                                                                                                   | [dsl/decisions/0001-language-style.md](../dsl/decisions/0001-language-style.md) §5                                                                                                                                            |

## Adjacent: open knobs awaiting reviewer input

[ir-v0.1.md §10](ir-v0.1.md) is now a closure log: it records which
previously-open knobs the audience and staging lenses (§1.1) closed.
All §10 entries are now closed under the combined lens; most carry a
cross-link to a row in this index when they have a post-v1 reopening
condition.

## Adjacent: post-v1 features (not "revisit", but "add when needed")

[ir-v0.1.md §2.2](ir-v0.1.md) lists features deliberately deferred from
v1 (sub-workflow calls, capability declarations, parallelism
annotations, block scope, nested loops, ...). Those are additive
post-v1 work, not reopenings of a closed v1 decision, and live in their
own table. Use this revisit-triggers index for "the v1 decision was X
and may need to flip to Y if Z is observed."
