Skip to content

Implementation Plan: Move smoke-test recipe from bundled to project-local#612

Merged
Trecek merged 7 commits intointegrationfrom
move-smoke-test-recipe-from-bundled-to-project-local/600
Apr 5, 2026
Merged

Implementation Plan: Move smoke-test recipe from bundled to project-local#612
Trecek merged 7 commits intointegrationfrom
move-smoke-test-recipe-from-bundled-to-project-local/600

Conversation

@Trecek
Copy link
Copy Markdown
Collaborator

@Trecek Trecek commented Apr 5, 2026

Summary

Move smoke-test.yaml and its companion artifacts (contract card, flow diagram) from the bundled src/autoskillit/recipes/ directory to the project-local .autoskillit/recipes/ directory. This makes smoke-test invisible to end-user projects while remaining fully functional when running from the AutoSkillit repository root. The existing project-local recipe discovery mechanism already supports this — no production code changes are needed. All changes are file relocations and test updates.

Requirements

MOVE — Recipe File Relocation

  • REQ-MOVE-001: The file src/autoskillit/recipes/smoke-test.yaml must be relocated to .autoskillit/recipes/smoke-test.yaml at the project root.
  • REQ-MOVE-002: Associated contract card(s) in src/autoskillit/recipes/contracts/ matching smoke-test* must be relocated to .autoskillit/recipes/contracts/.
  • REQ-MOVE-003: Associated diagram(s) in src/autoskillit/recipes/diagrams/ matching smoke-test* must be relocated to .autoskillit/recipes/diagrams/.

LIST — Listing Behavior

  • REQ-LIST-001: The smoke-test recipe must not appear in list_recipes output when the current working directory is outside the AutoSkillit repository.
  • REQ-LIST-002: The smoke-test recipe must appear in list_recipes output with source PROJECT when the current working directory is the AutoSkillit repository root.

LOAD — Pipeline Compatibility

  • REQ-LOAD-001: load_recipe("smoke-test") must succeed when invoked from the AutoSkillit repository root.
  • REQ-LOAD-002: Existing smoke-test pipeline execution must remain functionally identical after the move.

TEST — Test Updates

  • REQ-TEST-001: Tests that assert smoke-test has RecipeSource.BUILTIN must be updated to assert RecipeSource.PROJECT.
  • REQ-TEST-002: Tests that count the number of bundled recipes must be updated to reflect the removal of smoke-test from the bundled set.

Architecture Impact

Operational Diagram

%%{init: {'flowchart': {'nodeSpacing': 50, 'rankSpacing': 60, 'curve': 'basis'}}}%%
flowchart TB
    classDef cli fill:#1a237e,stroke:#7986cb,stroke-width:2px,color:#fff;
    classDef stateNode fill:#004d40,stroke:#4db6ac,stroke-width:2px,color:#fff;
    classDef handler fill:#e65100,stroke:#ffb74d,stroke-width:2px,color:#fff;
    classDef phase fill:#6a1b9a,stroke:#ba68c8,stroke-width:2px,color:#fff;
    classDef newComponent fill:#2e7d32,stroke:#81c784,stroke-width:2px,color:#fff;
    classDef output fill:#00695c,stroke:#4db6ac,stroke-width:2px,color:#fff;
    classDef detector fill:#b71c1c,stroke:#ef5350,stroke-width:2px,color:#fff;
    classDef terminal fill:#1a237e,stroke:#7986cb,stroke-width:2px,color:#fff;

    START(["list_recipes / find_recipe_by_name called"])

    subgraph ProjectLocal ["★ PROJECT-LOCAL SCAN (priority 1)"]
        direction TB
        PROJ_DIR["★ .autoskillit/recipes/<br/>━━━━━━━━━━<br/>source = PROJECT<br/>★ smoke-test.yaml (moved here)"]
        PROJ_CONTRACT["★ .autoskillit/recipes/contracts/<br/>━━━━━━━━━━<br/>★ smoke-test.yaml"]
        PROJ_DIAGRAM["★ .autoskillit/recipes/diagrams/<br/>━━━━━━━━━━<br/>★ smoke-test.md"]
    end

    subgraph Bundled ["BUNDLED SCAN (priority 2)"]
        direction TB
        BUILTIN_DIR["src/autoskillit/recipes/<br/>━━━━━━━━━━<br/>source = BUILTIN<br/>implementation, remediation,<br/>merge-prs, impl-groups<br/>(smoke-test removed)"]
    end

    DEDUP["Dedup via seen set<br/>━━━━━━━━━━<br/>Project names shadow bundled"]

    subgraph AutoskillitRepo ["AUTOSKILLIT REPO CONTEXT"]
        direction TB
        CLI_LIST["● autoskillit recipes list<br/>━━━━━━━━━━<br/>Shows smoke-test (source: project)"]
        CLI_ORDER["autoskillit order<br/>━━━━━━━━━━<br/>Pipeline execution menu"]
        CLI_RENDER["autoskillit recipes render<br/>━━━━━━━━━━<br/>_recipes_dir_for(PROJECT)<br/>→ .autoskillit/recipes/diagrams/"]
    end

    subgraph ExternalProject ["EXTERNAL PROJECT CONTEXT"]
        direction TB
        EXT_LIST["autoskillit recipes list<br/>━━━━━━━━━━<br/>smoke-test NOT visible<br/>(no project-local copy)"]
    end

    START --> PROJ_DIR
    PROJ_DIR --> DEDUP
    DEDUP --> BUILTIN_DIR
    PROJ_DIR --> PROJ_CONTRACT
    PROJ_DIR --> PROJ_DIAGRAM
    DEDUP --> CLI_LIST
    DEDUP --> CLI_ORDER
    CLI_RENDER --> PROJ_DIAGRAM
    DEDUP --> EXT_LIST

    class START terminal;
    class PROJ_DIR,PROJ_CONTRACT,PROJ_DIAGRAM newComponent;
    class BUILTIN_DIR stateNode;
    class DEDUP handler;
    class CLI_LIST,CLI_ORDER,CLI_RENDER cli;
    class EXT_LIST detector;
Loading

Module Dependency Diagram

%%{init: {'flowchart': {'nodeSpacing': 50, 'rankSpacing': 70, 'curve': 'basis'}}}%%
graph TB
    classDef cli fill:#1a237e,stroke:#7986cb,stroke-width:2px,color:#fff;
    classDef phase fill:#6a1b9a,stroke:#ba68c8,stroke-width:2px,color:#fff;
    classDef handler fill:#e65100,stroke:#ffb74d,stroke-width:2px,color:#fff;
    classDef stateNode fill:#004d40,stroke:#4db6ac,stroke-width:2px,color:#fff;
    classDef newComponent fill:#2e7d32,stroke:#81c784,stroke-width:2px,color:#fff;
    classDef output fill:#00695c,stroke:#4db6ac,stroke-width:2px,color:#fff;
    classDef integration fill:#c62828,stroke:#ef9a9a,stroke-width:2px,color:#fff;
    classDef detector fill:#b71c1c,stroke:#ef5350,stroke-width:2px,color:#fff;
    classDef terminal fill:#1a237e,stroke:#7986cb,stroke-width:2px,color:#fff;

    subgraph Tests ["TESTS (modified ●)"]
        direction TB
        T_SMOKE["● test_smoke_pipeline.py<br/>━━━━━━━━━━<br/>uses SMOKE_SCRIPT<br/>→ project-local path"]
        T_BUNDLED["● test_bundled_recipes.py<br/>━━━━━━━━━━<br/>smoke_yaml fixture<br/>→ project-local path"]
        T_POLICY["● test_bundled_recipe_hidden_policy.py<br/>━━━━━━━━━━<br/>BUNDLED_RECIPE_NAMES<br/>smoke-test removed"]
        T_TOOLS["● test_tools_recipe.py<br/>━━━━━━━━━━<br/>list_recipes assertion<br/>smoke-test NOT in bundled"]
        T_ENGINE["● test_engine.py<br/>━━━━━━━━━━<br/>contract adapter test<br/>→ project-local path"]
    end

    subgraph L3 ["L3 — SERVER"]
        direction TB
        TOOLS_RECIPE["server.tools_recipe<br/>━━━━━━━━━━<br/>list_recipes, load_recipe<br/>validate_recipe"]
    end

    subgraph L2R ["L2 — RECIPE"]
        direction TB
        RECIPE_IO["recipe.io<br/>━━━━━━━━━━<br/>builtin_recipes_dir()<br/>list_recipes()"]
        RECIPE_VALIDATOR["recipe.validator<br/>━━━━━━━━━━<br/>run_semantic_rules<br/>analyze_dataflow"]
        RECIPE_CONTRACTS["recipe.contracts<br/>━━━━━━━━━━<br/>load_bundled_manifest"]
    end

    subgraph L2M ["L2 — MIGRATION"]
        direction TB
        MIG_ENGINE["migration.engine<br/>━━━━━━━━━━<br/>default_migration_engine<br/>contract adapters"]
    end

    subgraph L0 ["L0 — CORE"]
        direction TB
        CORE_PATHS["core.paths<br/>━━━━━━━━━━<br/>pkg_root() → bundled dir<br/>fan-in: all layers"]
    end

    subgraph Artifacts ["★ PROJECT-LOCAL ARTIFACTS (new)"]
        direction TB
        PROJ_RECIPE["★ .autoskillit/recipes/<br/>━━━━━━━━━━<br/>smoke-test.yaml"]
        PROJ_CONTRACT["★ .autoskillit/recipes/contracts/<br/>━━━━━━━━━━<br/>smoke-test.yaml"]
        PROJ_DIAGRAM["★ .autoskillit/recipes/diagrams/<br/>━━━━━━━━━━<br/>smoke-test.md"]
    end

    T_SMOKE -->|"imports"| TOOLS_RECIPE
    T_SMOKE -->|"imports"| RECIPE_IO
    T_BUNDLED -->|"imports"| RECIPE_IO
    T_BUNDLED -->|"imports"| RECIPE_CONTRACTS
    T_POLICY -->|"imports"| CORE_PATHS
    T_TOOLS -->|"imports"| TOOLS_RECIPE
    T_ENGINE -->|"imports"| CORE_PATHS
    T_ENGINE -->|"imports"| MIG_ENGINE

    TOOLS_RECIPE -->|"imports"| RECIPE_IO
    RECIPE_IO -->|"builtin_recipes_dir()"| CORE_PATHS
    RECIPE_VALIDATOR -->|"imports"| RECIPE_IO
    RECIPE_CONTRACTS -->|"imports"| RECIPE_IO
    MIG_ENGINE -->|"imports"| CORE_PATHS

    T_SMOKE -.->|"now reads"| PROJ_RECIPE
    T_BUNDLED -.->|"now reads"| PROJ_RECIPE
    T_ENGINE -.->|"now reads"| PROJ_CONTRACT

    class T_SMOKE,T_BUNDLED,T_POLICY,T_TOOLS,T_ENGINE phase;
    class TOOLS_RECIPE cli;
    class RECIPE_IO,RECIPE_VALIDATOR,RECIPE_CONTRACTS handler;
    class MIG_ENGINE handler;
    class CORE_PATHS stateNode;
    class PROJ_RECIPE,PROJ_CONTRACT,PROJ_DIAGRAM newComponent;
Loading

Closes #600

Implementation Plan

Plan file: /home/talon/projects/autoskillit-runs/impl-20260404-190817-394673/.autoskillit/temp/make-plan/move_smoke_test_recipe_plan_2026-04-04_190817.md

🤖 Generated with Claude Code via AutoSkillit

Token Usage Summary

Step input output cached count time
plan 5.5k 76.5k 6.0M 5 32m 41s
verify 3.1k 86.2k 5.4M 5 31m 25s
implement 1.1k 116.2k 22.6M 6 50m 55s
fix 214 28.4k 3.5M 5 30m 58s
audit_impl 137 58.9k 3.1M 5 19m 28s
open_pr 74 37.1k 3.0M 2 12m 44s
Total 10.1k 403.4k 43.6M 2h 58m

Trecek and others added 4 commits April 4, 2026 19:34
Move smoke-test.yaml, its contract card, and flow diagram from
src/autoskillit/recipes/ to .autoskillit/recipes/ so the recipe
is only visible when running from the AutoSkillit repo root.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Point SMOKE_SCRIPT to .autoskillit/recipes/ instead of bundled dir
- Update smoke_recipe fixture to use SMOKE_SCRIPT constant
- Update smoke_project fixture to copy recipe into temp dir
- Add T1-T4 behavioral tests validating project-local discovery

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- test_bundled_recipes: point smoke_yaml fixture and standalone tests
  to .autoskillit/recipes/ path
- test_bundled_recipe_hidden_policy: remove smoke-test from bundled list
- test_tools_recipe: invert SS8 assertion (smoke-test not in empty project)
- test_engine: update ME13 source path to project-local location

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Auto-fix ruff format changes in test files
- Remove smoke-test entry from docs/recipes.md bundled section
- Update bundled recipe count from 6 to 5

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator Author

@Trecek Trecek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AutoSkillit PR Review — Verdict: changes_requested

"""smoke-test.yaml must exist in the project-local recipes directory."""
assert SMOKE_SCRIPT.exists()

async def test_smoke_test_source_is_project(self, smoke_project: Path) -> None:
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[warning] arch: test_smoke_test_source_is_project calls list_recipes() after smoke_project fixture chdirs. If list_recipes() caches the CWD at import time or uses a different resolution mechanism, this test may produce a false positive. The test has no assertion that list_recipes actually reads from tmp_path, not the real CWD or a module-level cache.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Investigated — this is intentional. list_recipes() calls Path.cwd() at runtime (tools_recipe.py:50: tool_ctx.recipes.list_all(Path.cwd())), so no module-level caching occurs. The smoke_project fixture's monkeypatch.chdir(tmp_path) correctly sets the CWD used when list_recipes() is called. This pattern is already validated bidirectionally by test_smoke_test_invisible_from_external_project (lines 426-435) which confirms CWD-awareness in both directions.

Copy link
Copy Markdown
Collaborator Author

@Trecek Trecek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AutoSkillit review found 8 blocking issues. See inline comments.

Summary: The core refactor (moving smoke-test from bundled to project-local) is correct and complete. The test updates properly reflect the new structure. However, the path resolution pattern used to locate the project-local recipe is inconsistent and fragile across 6+ test sites — the PROJECT_ROOT constant already defined in test_smoke_pipeline.py should be the single source of truth, not repeated Path(__file__).resolve().parent.parent.parent traversals. Additionally, two defensive gaps were found in the new tests.

Trecek and others added 3 commits April 4, 2026 20:31
…gine.py

- Add module-level PROJECT_ROOT constant (consistent with test_smoke_pipeline.py pattern)
  replacing fragile Path(__file__) traversal in test_contract_adapter_migrate_regenerates_card_on_disk
- Add assert src_recipe.exists() guard before shutil.copy2 for actionable failure messages

Addresses reviewer comments 3036345574 and 3036345580 on PR #612.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…CIPE constant

Add module-level PROJECT_ROOT and SMOKE_RECIPE constants to test_bundled_recipes.py,
replacing four inline Path(__file__).resolve().parent.parent.parent traversals
that duplicated the same fragile path assumption.

Addresses reviewer comments 3036345576, 3036345578, and 3036345585 on PR #612.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…oke_pipeline.py

- Add diagnostic message to assert SMOKE_SCRIPT.exists() check for actionable failures
- Replace next(generator) with next(generator, None) + explicit assert to produce
  AssertionError instead of StopIteration when smoke-test is missing from list_recipes

Addresses reviewer comments 3036345581 and 3036345583 on PR #612.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Trecek Trecek added this pull request to the merge queue Apr 5, 2026
Merged via the queue into integration with commit e7a95a9 Apr 5, 2026
2 checks passed
@Trecek Trecek deleted the move-smoke-test-recipe-from-bundled-to-project-local/600 branch April 5, 2026 03:57
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.

1 participant