Skip to content

Resolve depends_on half-enforcement in amplifier-bundle-recipes — pick A (advisory) or B (enforced) #297

@bkrabach

Description

@bkrabach

Filed in this repo because microsoft/amplifier-bundle-recipes has GitHub Issues disabled. The architecture question concerns the recipe engine in amplifier-bundle-recipes; please route to the recipe engine maintainers.

Background

Step.depends_on is currently half-enforced in the recipe engine.

  • The validator (validator.py:362-383, check_step_dependencies) rejects recipes where any depends_on target appears after its dependent step — load-time ERROR.
  • The executor (executor.py:710-733) iterates steps in strict declaration order via for i in range(...) and never consults depends_on at runtime.

The just-merged amplifier-bundle-recipes#76 (fix: collapse per-step depends_on warning to one per recipe) collapsed the per-step warning storm into a single per-recipe warning. That fixes the noise but leaves the underlying design question unresolved.

The three options

Option A — depends_on becomes advisory only

Delete the validator's ordering check. Document depends_on as advisory in the recipe schema. Possibly rename or deprecate the field. Keep the existence check.

  • Pros: honest; zero runtime change; removes conceptual debt; the per-recipe warning becomes the on-ramp to a future enforced version if one ever comes.
  • Cons: some recipe authors expected real semantics; they lose a guardrail.
  • Effort: ~1 day, one PR.

Option B — depends_on becomes enforced at execution time

Replace declaration-order iteration with topological-order iteration. Add cycle detection. Keep the validator check. Delete the warning. Optional follow-up: parallel execution for independent steps.

  • Pros: the field means what it says; enables future parallelism; aligns with Make, Airflow, Argo, GitHub Actions needs:, Prefect.
  • Cons: behavior change for every existing recipe; subtle break when a step relying on "B runs after A because declared after A" without saying so encounters a conditional skip; topological-sort failure modes; needs regression tests across foundation's recipes; invalidates the "execute in declaration order" mental model.
  • Effort: multi-week design + implementation, needs its own design doc first.

Option C — Status quo, better signaling

What amplifier-bundle-recipes#76 just shipped. One warning per recipe. Field remains half-enforced.

  • Pros: zero further work.
  • Cons: solves nothing structurally; the next maintainer revisits the same question.

Recommendation

Pick A. Plan for B only if/when parallel execution becomes valuable.

Sequencing:

  1. Recipe engine maintainers comment with A / B / C / other.
  2. If A: one PR (~1 day) — delete validator ordering check, update schema docs, optionally remove the per-recipe warning shipped in amplifier-bundle-recipes#76.
  3. If B: design doc first at docs/designs/depends-on-enforcement.md, then implementation PR(s).
  4. If C: close with rationale recorded.

Why A over B (briefly)

The engine has shipped, recipes exist, and "execute in declaration order" is the de-facto contract. Breaking it for a feature no current recipe relies on (parallelism, conditional-aware scheduling) is a bad trade. Option A's cost is roughly one PR. Option B's cost is a feature with a migration window. They are not the same shape of work.

If Option B becomes valuable later, Option A doesn't block it — you re-add the field's runtime semantics with full design discipline at that point. Option C blocks it by accumulating recipes built on ambiguous semantics.

References

Context

amplifier-bundle-recipes#76 introduced the per-recipe warning. The commit author of 8dae711 ("three COE-mandated fixes...") added the original per-step warning intentionally — they may have opinions on A vs B that should be captured here.

cc: please retag/relabel/transfer as appropriate for your team's design-tracking flow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions