Skip to content

recipes: migrate the 6 remaining legacy recipes to schema v2; agent-ref lint; validate-bundle-repo enhance_diagrams=false guard - #354

Merged
Brian Krabach (bkrabach) merged 2 commits into
mainfrom
fix/recipes-v2-migrate-remaining
Sep 3, 2026
Merged

recipes: migrate the 6 remaining legacy recipes to schema v2; agent-ref lint; validate-bundle-repo enhance_diagrams=false guard#354
Brian Krabach (bkrabach) merged 2 commits into
mainfrom
fix/recipes-v2-migrate-remaining

Conversation

@bkrabach

Copy link
Copy Markdown
Collaborator

Fixes the reported defect where validate-bundle-repo.yaml — and five sibling recipes — fail with Agent 'foundation:zen-architect' not found in configuration when run from any session whose bundle is not foundation.

Why it failed

Those recipes declared no schema_version / dependencies:, so the runner executed them in legacy-caller-bound mode, where agent: references resolve from the calling session's agent map rather than from the recipe's own declared closure. PR #345 fixed exactly this for three validator recipes; these six were left out of that migration.

The impact is worst for validate-bundle-repo, which is the repository-wide validator: its whole job is to be run against other repos by their own sessions — which are, almost by definition, not on the foundation bundle. It passed for its authors and hard-failed for its actual audience.

What changed

1. Six recipes migrated to schema v2. Each now declares schema_version: 2 plus a self-referential dependencies: block (foundation@v2.1.2), matching the convention #345 established:

  • validate-bundle-repo.yaml (5 agent refs)
  • bundle-behavioral-model.yaml
  • change-spec-to-behavioral-model.yaml
  • generate-bundle-docs.yaml
  • objectives-to-behavioral-model.yaml
  • spec-to-behavioral-model.yaml

2. Lint test to prevent recurrence. tests/test_yaml_structure_lint.py now asserts that every recipes/*.yaml carrying an agent: reference declares schema_version: 2 (+10 tests). A seventh recipe cannot regress into caller-bound mode unnoticed.

3. enhance_diagrams=false guard. validate-bundle-repo no longer crashes with Undefined variable: bundle_overview_enhanced_dot. The producing step declares that output and is skipped when diagrams are not enhanced, while the consumer read it unconditionally.

Verification

  • Suite: 1715 passed in the repo venv.
  • Live: all 7 runs completed under -b anchors-amp-dev — the six migrated recipes, plus validate-bundle-repo a second time with enhance_diagrams=false. Every run reported execution_mode: v2-closed-world-legacy-engine; zero occurrences of not found in configuration.
# reproduce the fix from a NON-foundation bundle
amplifier tool invoke recipes operation=execute \
  recipe_path=recipes/validate-bundle-repo.yaml \
  context='{"repo_path": "/path/to/any/repo"}'
# -> no legacy-caller-bound notice; zen-architect steps execute

Merge commits in this PR

  • Merge lane/recipes-l42: migrate 6 legacy recipes to schema v2 + agent-ref lint + validate-bundle-repo enhance guard

Breaking changes

None. The migrated recipes gain a declared closure; behavior for callers already on foundation is unchanged, and callers on other bundles go from hard failure to working.

Generated with Amplifier

Co-Authored-By: Amplifier 240397093+microsoft-amplifier@users.noreply.github.com

…ecipes-l42)

Every `agent:` reference in these six recipes previously resolved out of the
CALLING session's agent map -- the runner's `legacy-caller-bound` mode. A
caller on any bundle other than `foundation` failed at run time with
"Agent 'foundation:zen-architect' not found in configuration". PR #345 fixed
exactly this for validate-agents / validate-bundle / validate-single-bundle;
these six were not included, including validate-bundle-repo -- the
repository-wide validator, whose primary audience is by definition NOT on the
foundation bundle, and which carries the MOST references to the agent (5).

Under a v2-aware host those references now resolve from each recipe's own
declared closure, so that failure is structurally impossible.

  validate-bundle-repo            3.11.0 -> 3.12.0  (foundation:zen-architect)
  generate-bundle-docs             3.0.0 ->  3.1.0  (foundation:zen-architect)
  bundle-behavioral-model          1.0.0 ->  1.1.0  (explorer, file-ops)
  change-spec-to-behavioral-model  1.0.0 ->  1.1.0  (explorer, file-ops)
  objectives-to-behavioral-model   1.0.0 ->  1.1.0  (explorer, file-ops)
  spec-to-behavioral-model         1.0.0 ->  1.1.0  (explorer, file-ops)

The declaration is self-referential on purpose -- foundation's own recipes
declare foundation as a dependency. Core 11 forbids inferring a source from
the `foundation:` namespace prefix.

Also fixes the enhance_diagrams="false" crash
-------------------------------------------------------------------
validate-bundle-repo's `bundle-overview-regen-enhance` is conditional on
`{{enhance_diagrams}} != 'false'` but `bundle-overview-regen-write` read
{{bundle_overview_enhanced_dot}} unconditionally -> hard crash
`Undefined variable: {{bundle_overview_enhanced_dot}}`. New unconditional
`set-default-bundle-overview-enhanced-dot` step, declared AHEAD of the
conditional producer (steps execute in declaration order, so the real
producer overwrites the default) -- the same pattern validate-agents uses
for its set-default-* steps. The consumer already treats an empty value as
"no enhanced DOT" and falls back to the structural DOT.

generate-bundle-docs carried the byte-identical defect
(enhance-bundle-dot -> write-bundle-dot / {{enhanced_bundle_dot}}); fixed the
same way while migrating the file.

Two new lints, both proven to discriminate
-------------------------------------------------------------------
tests/test_yaml_structure_lint.py:

1. TestAgentRefsRequireSchemaV2 -- every recipes/*.yaml with an `agent:` step
   must declare schema_version 2 AND list every referenced agent under
   dependencies[].required_agents. Parsed, not grepped: several recipes embed
   Python samples containing the literal text `agent: str | None`, which a
   grep-based lint would flag. Also scans steps nested under `stages:`.

2. TestConditionalOutputsHaveDefaults -- a variable whose ONLY prior producer
   is a single conditional step must not be read later. Deliberately narrow to
   stay sound: complementary conditional pairs (build-check /
   set-default-build-check) and foreach `as:`/`collect:` bindings are modelled
   and NOT flagged, because a lint that fails correct recipes is worse than no
   lint.

Both include in-memory pre-fix/post-fix cases so the discrimination is
re-proven on every CI run, not just once by hand.

tests/test_module_dep_resolvability_check.py: version pin 3.11.0 -> 3.12.0.
The v3.11.0 changelog assertion is unaffected -- changelog entries accumulate.

Verification
-------------------------------------------------------------------
- Full suite: 1715 passed, 1 skipped (repo venv, Python 3.13.11).
- All 6 plan-verified with the shipped planner (FoundationResolver, NO caller
  agents anywhere): PARSE OK schema_version=2, PLAN OK, every referenced agent
  resolved from the declared closure at tag v2.1.2 (rev a27d582).
- Legacy loadability identical to the HEAD baseline for all 6:
  Recipe.from_yaml OK + validate_recipe VALID, errors=0 warnings=0.
- `recipe-runner validate`: status ok, schema_version 2, all 6.
- Discrimination proven live: stripping validate-bundle-repo's dependency
  block makes lint 1 fail naming the recipe and the agent; removing its
  set-default step makes lint 2 fail naming the consumer and the sole
  conditional producer. Both restored and re-verified green.

Source of truth: BUG-foundation-validate-bundle-repo-caller-bound.md
…-ref lint + validate-bundle-repo enhance guard
@bkrabach
Brian Krabach (bkrabach) merged commit 18efe87 into main Sep 3, 2026
7 checks passed
@bkrabach
Brian Krabach (bkrabach) deleted the fix/recipes-v2-migrate-remaining branch September 3, 2026 08:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants