From 9b2b425e60b08b9b5cb6c0fcbe68874b3c169534 Mon Sep 17 00:00:00 2001 From: Trecek Date: Mon, 20 Jul 2026 08:19:45 -0700 Subject: [PATCH 01/10] rename: pipeline health config field, ingredient, and docstring to pipeline_health Aligns naming across the config-default ingredient layer: - DiagnosticsConfig.post_run_analysis -> DiagnosticsConfig.pipeline_health - defaults.yaml diagnostics.post_run_analysis -> diagnostics.pipeline_health - CONFIG_DEFAULT_INGREDIENTS: post_run_diagnostics -> pipeline_health - resolve_ingredient_defaults: post_run_diagnostics -> pipeline_health - tools_kitchen.py open_kitchen docstring example updated The CONFIG_DEFAULT_INGREDIENTS membership, the str(bool).lower() derivation, the lock/override feedback-contract behavior, and the hidden: true + no authority: config attribute (preserving config-as-default) are unchanged. The rename carries forward the contract established in commit 838128fb0 (issue #4180) under the new canonical token. Co-Authored-By: Claude --- src/autoskillit/config/_config_dataclasses.py | 2 +- src/autoskillit/config/defaults.yaml | 2 +- src/autoskillit/config/ingredient_defaults.py | 6 +++--- src/autoskillit/server/tools/tools_kitchen.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/autoskillit/config/_config_dataclasses.py b/src/autoskillit/config/_config_dataclasses.py index d2b96a0c0..38952558e 100644 --- a/src/autoskillit/config/_config_dataclasses.py +++ b/src/autoskillit/config/_config_dataclasses.py @@ -305,7 +305,7 @@ class LoggingConfig: @dataclass class DiagnosticsConfig: - post_run_analysis: bool = False + pipeline_health: bool = False @dataclass diff --git a/src/autoskillit/config/defaults.yaml b/src/autoskillit/config/defaults.yaml index 11b18ea69..75786447b 100644 --- a/src/autoskillit/config/defaults.yaml +++ b/src/autoskillit/config/defaults.yaml @@ -118,7 +118,7 @@ logging: json_output: null diagnostics: - post_run_analysis: false + pipeline_health: false linux_tracing: enabled: true diff --git a/src/autoskillit/config/ingredient_defaults.py b/src/autoskillit/config/ingredient_defaults.py index 1dce9b5b1..32b264af5 100644 --- a/src/autoskillit/config/ingredient_defaults.py +++ b/src/autoskillit/config/ingredient_defaults.py @@ -135,7 +135,7 @@ def iter_display_categories( SERVER_AUTHORITATIVE_KEY_HINTS: dict[str, str] = {} -CONFIG_DEFAULT_INGREDIENTS: frozenset[str] = frozenset({"post_run_diagnostics"}) +CONFIG_DEFAULT_INGREDIENTS: frozenset[str] = frozenset({"pipeline_health"}) def build_config_default_layer(defaults: dict[str, str]) -> dict[str, str]: @@ -169,13 +169,13 @@ def resolve_ingredient_defaults(project_dir: Path) -> dict[str, str]: resolved["base_branch"] = cfg.branching.default_base_branch resolved["local_review_rounds"] = str(cfg.review.local_review_rounds) resolved["adversarial_review_level"] = cfg.plan.adversarial_review_level - resolved["post_run_diagnostics"] = str(cfg.diagnostics.post_run_analysis).lower() + resolved["pipeline_health"] = str(cfg.diagnostics.pipeline_health).lower() except Exception: logger.warning("resolve_base_branch_failed", exc_info=True) resolved["base_branch"] = "main" resolved["local_review_rounds"] = "0" resolved["adversarial_review_level"] = "auto" - resolved["post_run_diagnostics"] = "false" + resolved["pipeline_health"] = "false" # Fleet dispatch detection — reads env vars, not config, so must run unconditionally. resolved["is_fleet_dispatch"] = "true" if os.environ.get(DISPATCH_ID_ENV_VAR) else "false" diff --git a/src/autoskillit/server/tools/tools_kitchen.py b/src/autoskillit/server/tools/tools_kitchen.py index 6fdf1365a..c572b2180 100644 --- a/src/autoskillit/server/tools/tools_kitchen.py +++ b/src/autoskillit/server/tools/tools_kitchen.py @@ -787,7 +787,7 @@ async def open_kitchen( with ``authority: config`` (base_branch, local_review_rounds, adversarial_review_level) cannot be set via overrides — they resolve from server config and caller values are ignored with a warning. - Config-default ingredients (post_run_diagnostics) use config as the default + Config-default ingredients (pipeline_health) use config as the default but an explicit override wins. ingredients_only: When True and name is provided, return only the ingredient schema (ingredients_table, validity, suggestions) without the full recipe From 96fed608cc105de8ee598b843b0110b67e8fa897 Mon Sep 17 00:00:00 2001 From: Trecek Date: Mon, 20 Jul 2026 08:19:50 -0700 Subject: [PATCH 02/10] rename: pipeline health recipe YAML steps and JSON mirrors Renames all 5 bundled recipe files plus their regenerated JSON mirrors: - post_run_diagnostics ingredient input declaration -> pipeline_health - run_diagnostic* step keys -> pipeline_health* (no_ci, unconfirmed, error, no_changes, already_done, bare) - skip_when_false: inputs.post_run_diagnostics -> inputs.pipeline_health - with.step_name: post_run_diagnostics -> pipeline_health - All on_success/on_failure/on_context_limit/on_rate_limit route targets that referenced run_diagnostic* steps - promote-to-main.yaml dispatches[].skip_when references the renamed ingredient (structurally distinct from steps[].skip_when_false) recipe_source_hash on each regenerated contract card now reflects the new YAML content. JSON mirrors and contract cards are in sync with the YAML sources (check-contract-freshness hook passes). Co-Authored-By: Claude --- .../recipes/campaigns/promote-to-main.json | 4 +- .../recipes/campaigns/promote-to-main.yaml | 4 +- .../recipes/implementation-groups.json | 42 ++++++------- .../recipes/implementation-groups.yaml | 42 ++++++------- src/autoskillit/recipes/implementation.json | 62 +++++++++---------- src/autoskillit/recipes/implementation.yaml | 62 +++++++++---------- src/autoskillit/recipes/merge-prs.json | 22 +++---- src/autoskillit/recipes/merge-prs.yaml | 22 +++---- src/autoskillit/recipes/remediation.json | 62 +++++++++---------- src/autoskillit/recipes/remediation.yaml | 62 +++++++++---------- 10 files changed, 192 insertions(+), 192 deletions(-) diff --git a/src/autoskillit/recipes/campaigns/promote-to-main.json b/src/autoskillit/recipes/campaigns/promote-to-main.json index 0aff7b84c..14771d9c1 100644 --- a/src/autoskillit/recipes/campaigns/promote-to-main.json +++ b/src/autoskillit/recipes/campaigns/promote-to-main.json @@ -39,7 +39,7 @@ "default": "200000", "hidden": true }, - "post_run_diagnostics": { + "pipeline_health": { "description": "Run diagnostic analysis after pipeline completion", "default": "false", "hidden": true @@ -132,7 +132,7 @@ "name": "consolidate-diagnostics", "recipe": "consolidate-health-reports", "task": "Consolidate pipeline health reports from all dispatches in this campaign.", - "skip_when": "${{ inputs.post_run_diagnostics }} == false", + "skip_when": "${{ inputs.pipeline_health }} == false", "ingredients": { "kitchen_id": "${{ inputs.kitchen_id }}", "diagnostics_log_dir": "${{ inputs.diagnostics_log_dir }}" diff --git a/src/autoskillit/recipes/campaigns/promote-to-main.yaml b/src/autoskillit/recipes/campaigns/promote-to-main.yaml index 1b098c3e4..296e67185 100644 --- a/src/autoskillit/recipes/campaigns/promote-to-main.yaml +++ b/src/autoskillit/recipes/campaigns/promote-to-main.yaml @@ -36,7 +36,7 @@ ingredients: description: "Model context window in tokens; set to 1000000 for Opus 1M" default: "200000" hidden: true - post_run_diagnostics: + pipeline_health: description: Run diagnostic analysis after pipeline completion default: "false" hidden: true @@ -110,7 +110,7 @@ dispatches: - name: consolidate-diagnostics recipe: consolidate-health-reports task: "Consolidate pipeline health reports from all dispatches in this campaign." - skip_when: "${{ inputs.post_run_diagnostics }} == false" + skip_when: "${{ inputs.pipeline_health }} == false" ingredients: kitchen_id: "${{ inputs.kitchen_id }}" diagnostics_log_dir: "${{ inputs.diagnostics_log_dir }}" diff --git a/src/autoskillit/recipes/implementation-groups.json b/src/autoskillit/recipes/implementation-groups.json index e8f9d2c7d..be46944cb 100644 --- a/src/autoskillit/recipes/implementation-groups.json +++ b/src/autoskillit/recipes/implementation-groups.json @@ -106,7 +106,7 @@ "default": "false", "hidden": true }, - "post_run_diagnostics": { + "pipeline_health": { "description": "Run diagnostic analysis after pipeline completion", "default": "false", "hidden": true @@ -1605,20 +1605,20 @@ "status": "error", "step_name": "register_clone_no_ci" }, - "on_success": "run_diagnostic_no_ci", - "on_failure": "run_diagnostic_no_ci" + "on_success": "pipeline_health_no_ci", + "on_failure": "pipeline_health_no_ci" }, - "run_diagnostic_no_ci": { + "pipeline_health_no_ci": { "description": "Run post-pipeline diagnostic analysis on session logs (no-CI path)", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "escalate_stop_no_ci", "on_failure": "escalate_stop_no_ci", @@ -2518,21 +2518,21 @@ "status": "unconfirmed", "step_name": "register_clone_unconfirmed" }, - "on_success": "run_diagnostic_unconfirmed", - "on_failure": "run_diagnostic_unconfirmed", + "on_success": "pipeline_health_unconfirmed", + "on_failure": "pipeline_health_unconfirmed", "note": "Called when a merge-wait step times out before merge is confirmed. Does NOT call release_issue — the in-progress label stays on the issue so operators can see the PR is still actively queued. The clone is preserved (status: unconfirmed) for human inspection.\n" }, - "run_diagnostic_unconfirmed": { + "pipeline_health_unconfirmed": { "description": "Run post-pipeline diagnostic analysis (unconfirmed path)", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "done_unconfirmed", "on_failure": "done_unconfirmed", @@ -2634,20 +2634,20 @@ "status": "success", "step_name": "register_clone_success" }, - "on_success": "run_diagnostic", - "on_failure": "run_diagnostic" + "on_success": "pipeline_health", + "on_failure": "pipeline_health" }, - "run_diagnostic": { + "pipeline_health": { "description": "Run post-pipeline diagnostic analysis on session logs", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "done", "on_failure": "done", @@ -2663,20 +2663,20 @@ "status": "error", "step_name": "register_clone_failure" }, - "on_success": "run_diagnostic_error", - "on_failure": "run_diagnostic_error" + "on_success": "pipeline_health_error", + "on_failure": "pipeline_health_error" }, - "run_diagnostic_error": { + "pipeline_health_error": { "description": "Run post-pipeline diagnostic analysis on session logs (error path)", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "escalate_stop", "on_failure": "escalate_stop", diff --git a/src/autoskillit/recipes/implementation-groups.yaml b/src/autoskillit/recipes/implementation-groups.yaml index 81431b635..22e40aebc 100644 --- a/src/autoskillit/recipes/implementation-groups.yaml +++ b/src/autoskillit/recipes/implementation-groups.yaml @@ -91,7 +91,7 @@ ingredients: description: "Set to 'true' when process-issues has already claimed this issue upfront. Allows claim_issue defense step to pass through without aborting." default: "false" hidden: true - post_run_diagnostics: + pipeline_health: description: Run diagnostic analysis after pipeline completion default: 'false' hidden: true @@ -1440,21 +1440,21 @@ steps: clone_path: "${{ context.work_dir }}" status: "error" step_name: register_clone_no_ci - on_success: run_diagnostic_no_ci - on_failure: run_diagnostic_no_ci + on_success: pipeline_health_no_ci + on_failure: pipeline_health_no_ci - run_diagnostic_no_ci: + pipeline_health_no_ci: description: Run post-pipeline diagnostic analysis on session logs (no-CI path) tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: escalate_stop_no_ci on_failure: escalate_stop_no_ci on_context_limit: escalate_stop_no_ci @@ -2252,26 +2252,26 @@ steps: clone_path: "${{ context.work_dir }}" status: "unconfirmed" step_name: register_clone_unconfirmed - on_success: run_diagnostic_unconfirmed - on_failure: run_diagnostic_unconfirmed + on_success: pipeline_health_unconfirmed + on_failure: pipeline_health_unconfirmed note: > Called when a merge-wait step times out before merge is confirmed. Does NOT call release_issue — the in-progress label stays on the issue so operators can see the PR is still actively queued. The clone is preserved (status: unconfirmed) for human inspection. - run_diagnostic_unconfirmed: + pipeline_health_unconfirmed: description: Run post-pipeline diagnostic analysis (unconfirmed path) tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: done_unconfirmed on_failure: done_unconfirmed on_context_limit: done_unconfirmed @@ -2390,21 +2390,21 @@ steps: clone_path: "${{ context.work_dir }}" status: "success" step_name: register_clone_success - on_success: run_diagnostic - on_failure: run_diagnostic + on_success: pipeline_health + on_failure: pipeline_health - run_diagnostic: + pipeline_health: description: Run post-pipeline diagnostic analysis on session logs tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: done on_failure: done on_context_limit: done @@ -2420,21 +2420,21 @@ steps: clone_path: "${{ context.work_dir }}" status: "error" step_name: register_clone_failure - on_success: run_diagnostic_error - on_failure: run_diagnostic_error + on_success: pipeline_health_error + on_failure: pipeline_health_error - run_diagnostic_error: + pipeline_health_error: description: Run post-pipeline diagnostic analysis on session logs (error path) tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: escalate_stop on_failure: escalate_stop on_context_limit: escalate_stop diff --git a/src/autoskillit/recipes/implementation.json b/src/autoskillit/recipes/implementation.json index 1f7641bcc..823f485a2 100644 --- a/src/autoskillit/recipes/implementation.json +++ b/src/autoskillit/recipes/implementation.json @@ -116,7 +116,7 @@ "default": "6", "hidden": true }, - "post_run_diagnostics": { + "pipeline_health": { "description": "Run diagnostic analysis after pipeline completion", "default": "false", "hidden": true @@ -1677,20 +1677,20 @@ "status": "error", "step_name": "register_clone_no_ci" }, - "on_success": "run_diagnostic_no_ci", - "on_failure": "run_diagnostic_no_ci" + "on_success": "pipeline_health_no_ci", + "on_failure": "pipeline_health_no_ci" }, - "run_diagnostic_no_ci": { + "pipeline_health_no_ci": { "description": "Run post-pipeline diagnostic analysis on session logs (no-CI path)", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "escalate_stop_no_ci", "on_failure": "escalate_stop_no_ci", @@ -2657,21 +2657,21 @@ "status": "unconfirmed", "step_name": "register_clone_unconfirmed" }, - "on_success": "run_diagnostic_unconfirmed", - "on_failure": "run_diagnostic_unconfirmed", + "on_success": "pipeline_health_unconfirmed", + "on_failure": "pipeline_health_unconfirmed", "note": "Called when a merge-wait step times out before merge is confirmed. Does NOT call release_issue — the in-progress label stays on the issue so operators can see the PR is still actively queued. The clone is preserved (status: unconfirmed) for human inspection.\n" }, - "run_diagnostic_unconfirmed": { + "pipeline_health_unconfirmed": { "description": "Run post-pipeline diagnostic analysis on session logs (unconfirmed path)", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "done_unconfirmed", "on_failure": "done_unconfirmed", @@ -2703,8 +2703,8 @@ "status": "success", "step_name": "register_clone_success" }, - "on_success": "run_diagnostic", - "on_failure": "run_diagnostic" + "on_success": "pipeline_health", + "on_failure": "pipeline_health" }, "register_clone_failure": { "description": "Register clone as preserved (error pipeline)", @@ -2714,20 +2714,20 @@ "status": "error", "step_name": "register_clone_failure" }, - "on_success": "run_diagnostic_error", - "on_failure": "run_diagnostic_error" + "on_success": "pipeline_health_error", + "on_failure": "pipeline_health_error" }, - "run_diagnostic": { + "pipeline_health": { "description": "Run post-pipeline diagnostic analysis on session logs", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "done", "on_failure": "done", @@ -2735,17 +2735,17 @@ "on_rate_limit": "done", "note": "Execute this diagnostic step. Failures are logged but do not alter pipeline routing. Both on_failure and on_context_limit route to the same terminal as on_success.\n" }, - "run_diagnostic_error": { + "pipeline_health_error": { "description": "Run post-pipeline diagnostic analysis on session logs (error path)", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "escalate_stop", "on_failure": "escalate_stop", @@ -2761,20 +2761,20 @@ "status": "success", "step_name": "register_clone_no_changes" }, - "on_success": "run_diagnostic_no_changes", - "on_failure": "run_diagnostic_no_changes" + "on_success": "pipeline_health_no_changes", + "on_failure": "pipeline_health_no_changes" }, - "run_diagnostic_no_changes": { + "pipeline_health_no_changes": { "description": "Run post-pipeline diagnostic analysis (zero-change path)", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "done_no_changes", "on_failure": "done_no_changes", @@ -2790,20 +2790,20 @@ "status": "success", "step_name": "register_clone_already_done" }, - "on_success": "run_diagnostic_already_done", - "on_failure": "run_diagnostic_already_done" + "on_success": "pipeline_health_already_done", + "on_failure": "pipeline_health_already_done" }, - "run_diagnostic_already_done": { + "pipeline_health_already_done": { "description": "Run post-pipeline diagnostic analysis (already-done path)", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "done_already_done", "on_failure": "done_already_done", diff --git a/src/autoskillit/recipes/implementation.yaml b/src/autoskillit/recipes/implementation.yaml index d458f886d..30285621b 100644 --- a/src/autoskillit/recipes/implementation.yaml +++ b/src/autoskillit/recipes/implementation.yaml @@ -107,7 +107,7 @@ ingredients: to build-execution-map. Must be a positive integer (expressed as a string). default: '6' hidden: true - post_run_diagnostics: + pipeline_health: description: Run diagnostic analysis after pipeline completion default: 'false' hidden: true @@ -1524,21 +1524,21 @@ steps: clone_path: ${{ context.work_dir }} status: error step_name: register_clone_no_ci - on_success: run_diagnostic_no_ci - on_failure: run_diagnostic_no_ci - run_diagnostic_no_ci: + on_success: pipeline_health_no_ci + on_failure: pipeline_health_no_ci + pipeline_health_no_ci: description: Run post-pipeline diagnostic analysis on session logs (no-CI path) tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: escalate_stop_no_ci on_failure: escalate_stop_no_ci on_context_limit: escalate_stop_no_ci @@ -2420,28 +2420,28 @@ steps: clone_path: ${{ context.work_dir }} status: unconfirmed step_name: register_clone_unconfirmed - on_success: run_diagnostic_unconfirmed - on_failure: run_diagnostic_unconfirmed + on_success: pipeline_health_unconfirmed + on_failure: pipeline_health_unconfirmed note: 'Called when a merge-wait step times out before merge is confirmed. Does NOT call release_issue — the in-progress label stays on the issue so operators can see the PR is still actively queued. The clone is preserved (status: unconfirmed) for human inspection. ' - run_diagnostic_unconfirmed: + pipeline_health_unconfirmed: description: Run post-pipeline diagnostic analysis on session logs (unconfirmed path) tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: done_unconfirmed on_failure: done_unconfirmed on_context_limit: done_unconfirmed @@ -2475,8 +2475,8 @@ steps: clone_path: ${{ context.work_dir }} status: success step_name: register_clone_success - on_success: run_diagnostic - on_failure: run_diagnostic + on_success: pipeline_health + on_failure: pipeline_health register_clone_failure: description: Register clone as preserved (error pipeline) tool: register_clone_status @@ -2484,21 +2484,21 @@ steps: clone_path: ${{ context.work_dir }} status: error step_name: register_clone_failure - on_success: run_diagnostic_error - on_failure: run_diagnostic_error - run_diagnostic: + on_success: pipeline_health_error + on_failure: pipeline_health_error + pipeline_health: description: Run post-pipeline diagnostic analysis on session logs tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: done on_failure: done on_context_limit: done @@ -2507,19 +2507,19 @@ steps: routing. Both on_failure and on_context_limit route to the same terminal as on_success. ' - run_diagnostic_error: + pipeline_health_error: description: Run post-pipeline diagnostic analysis on session logs (error path) tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: escalate_stop on_failure: escalate_stop on_context_limit: escalate_stop @@ -2535,21 +2535,21 @@ steps: clone_path: ${{ context.work_dir }} status: success step_name: register_clone_no_changes - on_success: run_diagnostic_no_changes - on_failure: run_diagnostic_no_changes - run_diagnostic_no_changes: + on_success: pipeline_health_no_changes + on_failure: pipeline_health_no_changes + pipeline_health_no_changes: description: Run post-pipeline diagnostic analysis (zero-change path) tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: done_no_changes on_failure: done_no_changes on_context_limit: done_no_changes @@ -2565,21 +2565,21 @@ steps: clone_path: ${{ context.work_dir }} status: success step_name: register_clone_already_done - on_success: run_diagnostic_already_done - on_failure: run_diagnostic_already_done - run_diagnostic_already_done: + on_success: pipeline_health_already_done + on_failure: pipeline_health_already_done + pipeline_health_already_done: description: Run post-pipeline diagnostic analysis (already-done path) tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: done_already_done on_failure: done_already_done on_context_limit: done_already_done diff --git a/src/autoskillit/recipes/merge-prs.json b/src/autoskillit/recipes/merge-prs.json index 4f211af5f..dc1f20c2a 100644 --- a/src/autoskillit/recipes/merge-prs.json +++ b/src/autoskillit/recipes/merge-prs.json @@ -42,7 +42,7 @@ "description": "Plan files for audit", "default": "{{AUTOSKILLIT_TEMP}}/merge-prs" }, - "post_run_diagnostics": { + "pipeline_health": { "description": "Run diagnostic analysis after pipeline completion", "default": "false", "hidden": true @@ -1792,8 +1792,8 @@ "status": "success", "step_name": "register_clone_success" }, - "on_success": "run_diagnostic", - "on_failure": "run_diagnostic" + "on_success": "pipeline_health", + "on_failure": "pipeline_health" }, "register_clone_failure": { "description": "Register clone as preserved (error pipeline)", @@ -1803,20 +1803,20 @@ "status": "error", "step_name": "register_clone_failure" }, - "on_success": "run_diagnostic_error", - "on_failure": "run_diagnostic_error" + "on_success": "pipeline_health_error", + "on_failure": "pipeline_health_error" }, - "run_diagnostic": { + "pipeline_health": { "description": "Run post-pipeline diagnostic analysis on session logs", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "done", "on_failure": "done", @@ -1824,17 +1824,17 @@ "on_rate_limit": "done", "note": "Execute this diagnostic step. Failures are logged but do not alter pipeline routing. Both on_failure and on_context_limit route to the same terminal as on_success.\n" }, - "run_diagnostic_error": { + "pipeline_health_error": { "description": "Run post-pipeline diagnostic analysis on session logs (error path)", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "escalate_stop", "on_failure": "escalate_stop", diff --git a/src/autoskillit/recipes/merge-prs.yaml b/src/autoskillit/recipes/merge-prs.yaml index 2926334cd..376e7510a 100644 --- a/src/autoskillit/recipes/merge-prs.yaml +++ b/src/autoskillit/recipes/merge-prs.yaml @@ -39,7 +39,7 @@ ingredients: plans_dir: description: Plan files for audit default: '{{AUTOSKILLIT_TEMP}}/merge-prs' - post_run_diagnostics: + pipeline_health: description: Run diagnostic analysis after pipeline completion default: 'false' hidden: true @@ -1729,8 +1729,8 @@ steps: clone_path: ${{ context.work_dir }} status: success step_name: register_clone_success - on_success: run_diagnostic - on_failure: run_diagnostic + on_success: pipeline_health + on_failure: pipeline_health register_clone_failure: description: Register clone as preserved (error pipeline) tool: register_clone_status @@ -1738,21 +1738,21 @@ steps: clone_path: ${{ context.work_dir }} status: error step_name: register_clone_failure - on_success: run_diagnostic_error - on_failure: run_diagnostic_error - run_diagnostic: + on_success: pipeline_health_error + on_failure: pipeline_health_error + pipeline_health: description: Run post-pipeline diagnostic analysis on session logs tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: done on_failure: done on_context_limit: done @@ -1761,19 +1761,19 @@ steps: routing. Both on_failure and on_context_limit route to the same terminal as on_success. ' - run_diagnostic_error: + pipeline_health_error: description: Run post-pipeline diagnostic analysis on session logs (error path) tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: escalate_stop on_failure: escalate_stop on_context_limit: escalate_stop diff --git a/src/autoskillit/recipes/remediation.json b/src/autoskillit/recipes/remediation.json index f2bd21282..dfc0fa4f7 100644 --- a/src/autoskillit/recipes/remediation.json +++ b/src/autoskillit/recipes/remediation.json @@ -128,7 +128,7 @@ "default": "6", "hidden": true }, - "post_run_diagnostics": { + "pipeline_health": { "description": "Run diagnostic analysis after pipeline completion", "default": "false", "hidden": true @@ -1891,20 +1891,20 @@ "status": "error", "step_name": "register_clone_no_ci" }, - "on_success": "run_diagnostic_no_ci", - "on_failure": "run_diagnostic_no_ci" + "on_success": "pipeline_health_no_ci", + "on_failure": "pipeline_health_no_ci" }, - "run_diagnostic_no_ci": { + "pipeline_health_no_ci": { "description": "Run post-pipeline diagnostic analysis on session logs (no-CI path)", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "escalate_stop_no_ci", "on_failure": "escalate_stop_no_ci", @@ -2843,21 +2843,21 @@ "status": "unconfirmed", "step_name": "register_clone_unconfirmed" }, - "on_success": "run_diagnostic_unconfirmed", - "on_failure": "run_diagnostic_unconfirmed", + "on_success": "pipeline_health_unconfirmed", + "on_failure": "pipeline_health_unconfirmed", "note": "Called when a merge-wait step times out before merge is confirmed. Does NOT call release_issue — the in-progress label stays on the issue so operators can see the PR is still actively queued. The clone is preserved (status: unconfirmed) for human inspection.\n" }, - "run_diagnostic_unconfirmed": { + "pipeline_health_unconfirmed": { "description": "Run post-pipeline diagnostic analysis on session logs (unconfirmed path)", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "done_unconfirmed", "on_failure": "done_unconfirmed", @@ -2917,8 +2917,8 @@ "status": "success", "step_name": "register_clone_success" }, - "on_success": "run_diagnostic", - "on_failure": "run_diagnostic" + "on_success": "pipeline_health", + "on_failure": "pipeline_health" }, "register_clone_failure": { "description": "Register clone as preserved (error pipeline)", @@ -2928,20 +2928,20 @@ "status": "error", "step_name": "register_clone_failure" }, - "on_success": "run_diagnostic_error", - "on_failure": "run_diagnostic_error" + "on_success": "pipeline_health_error", + "on_failure": "pipeline_health_error" }, - "run_diagnostic": { + "pipeline_health": { "description": "Run post-pipeline diagnostic analysis on session logs", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "done", "on_failure": "done", @@ -2949,17 +2949,17 @@ "on_rate_limit": "done", "note": "Execute this diagnostic step. Failures are logged but do not alter pipeline routing. Both on_failure and on_context_limit route to the same terminal as on_success.\n" }, - "run_diagnostic_error": { + "pipeline_health_error": { "description": "Run post-pipeline diagnostic analysis on session logs (error path)", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "escalate_stop", "on_failure": "escalate_stop", @@ -2975,20 +2975,20 @@ "status": "success", "step_name": "register_clone_no_changes" }, - "on_success": "run_diagnostic_no_changes", - "on_failure": "run_diagnostic_no_changes" + "on_success": "pipeline_health_no_changes", + "on_failure": "pipeline_health_no_changes" }, - "run_diagnostic_no_changes": { + "pipeline_health_no_changes": { "description": "Run post-pipeline diagnostic analysis (zero-change path)", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "done_no_changes", "on_failure": "done_no_changes", @@ -3004,20 +3004,20 @@ "status": "success", "step_name": "register_clone_already_done" }, - "on_success": "run_diagnostic_already_done", - "on_failure": "run_diagnostic_already_done" + "on_success": "pipeline_health_already_done", + "on_failure": "pipeline_health_already_done" }, - "run_diagnostic_already_done": { + "pipeline_health_already_done": { "description": "Run post-pipeline diagnostic analysis (already-done path)", "tool": "run_skill", "model": "", "stale_threshold": 2400, "optional": true, - "skip_when_false": "inputs.post_run_diagnostics", + "skip_when_false": "inputs.pipeline_health", "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "post_run_diagnostics" + "step_name": "pipeline_health" }, "on_success": "done_already_done", "on_failure": "done_already_done", diff --git a/src/autoskillit/recipes/remediation.yaml b/src/autoskillit/recipes/remediation.yaml index 8b7cf5821..d82a343ec 100644 --- a/src/autoskillit/recipes/remediation.yaml +++ b/src/autoskillit/recipes/remediation.yaml @@ -140,7 +140,7 @@ ingredients: to build-execution-map. Must be a positive integer (expressed as a string). default: '6' hidden: true - post_run_diagnostics: + pipeline_health: description: Run diagnostic analysis after pipeline completion default: 'false' hidden: true @@ -1719,21 +1719,21 @@ steps: clone_path: ${{ context.work_dir }} status: error step_name: register_clone_no_ci - on_success: run_diagnostic_no_ci - on_failure: run_diagnostic_no_ci - run_diagnostic_no_ci: + on_success: pipeline_health_no_ci + on_failure: pipeline_health_no_ci + pipeline_health_no_ci: description: Run post-pipeline diagnostic analysis on session logs (no-CI path) tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: escalate_stop_no_ci on_failure: escalate_stop_no_ci on_context_limit: escalate_stop_no_ci @@ -2581,28 +2581,28 @@ steps: clone_path: ${{ context.work_dir }} status: unconfirmed step_name: register_clone_unconfirmed - on_success: run_diagnostic_unconfirmed - on_failure: run_diagnostic_unconfirmed + on_success: pipeline_health_unconfirmed + on_failure: pipeline_health_unconfirmed note: 'Called when a merge-wait step times out before merge is confirmed. Does NOT call release_issue — the in-progress label stays on the issue so operators can see the PR is still actively queued. The clone is preserved (status: unconfirmed) for human inspection. ' - run_diagnostic_unconfirmed: + pipeline_health_unconfirmed: description: Run post-pipeline diagnostic analysis on session logs (unconfirmed path) tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: done_unconfirmed on_failure: done_unconfirmed on_context_limit: done_unconfirmed @@ -2668,8 +2668,8 @@ steps: clone_path: ${{ context.work_dir }} status: success step_name: register_clone_success - on_success: run_diagnostic - on_failure: run_diagnostic + on_success: pipeline_health + on_failure: pipeline_health register_clone_failure: description: Register clone as preserved (error pipeline) tool: register_clone_status @@ -2677,21 +2677,21 @@ steps: clone_path: ${{ context.work_dir }} status: error step_name: register_clone_failure - on_success: run_diagnostic_error - on_failure: run_diagnostic_error - run_diagnostic: + on_success: pipeline_health_error + on_failure: pipeline_health_error + pipeline_health: description: Run post-pipeline diagnostic analysis on session logs tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: done on_failure: done on_context_limit: done @@ -2700,19 +2700,19 @@ steps: routing. Both on_failure and on_context_limit route to the same terminal as on_success. ' - run_diagnostic_error: + pipeline_health_error: description: Run post-pipeline diagnostic analysis on session logs (error path) tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: escalate_stop on_failure: escalate_stop on_context_limit: escalate_stop @@ -2728,21 +2728,21 @@ steps: clone_path: ${{ context.work_dir }} status: success step_name: register_clone_no_changes - on_success: run_diagnostic_no_changes - on_failure: run_diagnostic_no_changes - run_diagnostic_no_changes: + on_success: pipeline_health_no_changes + on_failure: pipeline_health_no_changes + pipeline_health_no_changes: description: Run post-pipeline diagnostic analysis (zero-change path) tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: done_no_changes on_failure: done_no_changes on_context_limit: done_no_changes @@ -2758,21 +2758,21 @@ steps: clone_path: ${{ context.work_dir }} status: success step_name: register_clone_already_done - on_success: run_diagnostic_already_done - on_failure: run_diagnostic_already_done - run_diagnostic_already_done: + on_success: pipeline_health_already_done + on_failure: pipeline_health_already_done + pipeline_health_already_done: description: Run post-pipeline diagnostic analysis (already-done path) tool: run_skill model: '' stale_threshold: 2400 optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: post_run_diagnostics + step_name: pipeline_health on_success: done_already_done on_failure: done_already_done on_context_limit: done_already_done From 592a9dfccbf018b86e088318ab00d7bca1c03dee Mon Sep 17 00:00:00 2001 From: Trecek Date: Mon, 20 Jul 2026 08:19:58 -0700 Subject: [PATCH 03/10] rename: pipeline health test references across config/recipe/server/arch/infra/execution Updates 18 test files (mechanical rename only, no new test logic): - tests/config/test_config.py: post_run_analysis -> pipeline_health - tests/config/test_helpers.py: function renames + post_run_diagnostics string literals -> pipeline_health (test functions: includes_/not_/in_) - tests/recipe/test_*: post_run_diagnostics -> pipeline_health, all run_diagnostic* step-name references -> pipeline_health*, function names + docstrings referencing the legacy names - tests/server/test_tools_kitchen_envelope.py: demotion tests (override_wins/config_default_applied) renamed; all string literals - tests/server/test_lock_ingredients.py: test_post_run_diagnostics_lockable -> test_pipeline_health_lockable - tests/server/_helpers.py + test_mcp_overrides.py: dict key + comment - tests/infra/test_pretty_output_recipe.py + tests/arch/test_subpackage_ isolation.py + tests/execution/backends/test_cli_conformance_probes.py: passing references in test fixtures, docstrings, and probe prompts All tests already cover the contracts (config-default, override-wins, lockability, skip_when_false, routing); this is purely a naming alignment to the canonical pipeline_health token. Co-Authored-By: Claude --- tests/arch/test_subpackage_isolation.py | 2 +- tests/config/test_config.py | 14 +++++----- tests/config/test_helpers.py | 20 ++++++------- .../backends/test_cli_conformance_probes.py | 2 +- tests/infra/test_pretty_output_recipe.py | 2 +- .../recipe/test_bundled_recipes_all_truthy.py | 2 +- tests/recipe/test_bundled_recipes_general.py | 14 +++++----- .../test_check_ci_already_passed_routing.py | 16 +++++------ tests/recipe/test_diagnostic_steps.py | 22 +++++++-------- tests/recipe/test_hidden_ingredients.py | 28 +++++++++---------- tests/recipe/test_implementation.py | 14 +++++----- ..._implementation_groups_pr_decomposition.py | 6 ++-- tests/recipe/test_remediation_recipe.py | 14 +++++----- tests/server/_helpers.py | 2 +- tests/server/test_lock_ingredients.py | 12 +++----- tests/server/test_mcp_overrides.py | 4 +-- tests/server/test_tools_kitchen_envelope.py | 28 +++++++++---------- 17 files changed, 97 insertions(+), 105 deletions(-) diff --git a/tests/arch/test_subpackage_isolation.py b/tests/arch/test_subpackage_isolation.py index d6bfaf483..288abb401 100644 --- a/tests/arch/test_subpackage_isolation.py +++ b/tests/arch/test_subpackage_isolation.py @@ -1013,7 +1013,7 @@ def test_data_directories_are_not_python_packages() -> None: "_dispatch_infeasible_response accepting capability_detail kwarg for none_pass " "diagnostic enrichment (+24 net lines)" "; config-default ingredient layer: build_config_default_layer call and " - "docstring update for post_run_diagnostics demotion (+10 net lines)" + "docstring update for pipeline_health demotion (+10 net lines)" "; get_recipe session_serve_overrides replay via serve_recipe; " "deferred-recall snapshot update guard (+3 net lines)" "; per-step backend override config_backend kwarg threading (+5 net lines)" diff --git a/tests/config/test_config.py b/tests/config/test_config.py index 4f92813cd..023835ef6 100644 --- a/tests/config/test_config.py +++ b/tests/config/test_config.py @@ -48,9 +48,9 @@ def test_default_model_config(self): assert cfg.model.provider == "anthropic" def test_diagnostics_config_defaults(self): - """DIAG_C1: DiagnosticsConfig.post_run_analysis defaults to False.""" + """DIAG_C1: DiagnosticsConfig.pipeline_health defaults to False.""" cfg = AutomationConfig() - assert cfg.diagnostics.post_run_analysis is False + assert cfg.diagnostics.pipeline_health is False def test_model_provider_custom(self): """MOD_C4: CoreRunConfig accepts custom provider.""" @@ -173,14 +173,14 @@ def test_load_yaml_full_config(self, tmp_path): assert cfg.worktree_setup.command == ["task", "install-worktree"] def test_load_diagnostics_config(self, tmp_path): - """DIAG_C2: diagnostics.post_run_analysis can be set via YAML.""" + """DIAG_C2: diagnostics.pipeline_health can be set via YAML.""" config_dir = tmp_path / ".autoskillit" config_dir.mkdir() (config_dir / "config.yaml").write_text( - yaml.dump({"diagnostics": {"post_run_analysis": True}}) + yaml.dump({"diagnostics": {"pipeline_health": True}}) ) cfg = load_config(tmp_path) - assert cfg.diagnostics.post_run_analysis is True + assert cfg.diagnostics.pipeline_health is True def test_partial_yaml_preserves_defaults(self, tmp_path): """C4: YAML with only test_check.command -> other fields keep defaults.""" @@ -290,9 +290,9 @@ def test_yaml_loads_model_config(self, tmp_path): assert cfg.model.provider == "anthropic" def test_diagnostics_config_defaults(self): - """DIAG_C1: DiagnosticsConfig.post_run_analysis defaults to False.""" + """DIAG_C1: DiagnosticsConfig.pipeline_health defaults to False.""" cfg = AutomationConfig() - assert cfg.diagnostics.post_run_analysis is False + assert cfg.diagnostics.pipeline_health is False def test_yaml_loads_model_provider(self, tmp_path): """MOD_C5: YAML model.provider loads into CoreRunConfig.provider.""" diff --git a/tests/config/test_helpers.py b/tests/config/test_helpers.py index 765dbeb1b..6c506fce3 100644 --- a/tests/config/test_helpers.py +++ b/tests/config/test_helpers.py @@ -77,8 +77,8 @@ def test_resolve_ingredient_defaults_includes_adversarial_review_level(tmp_path) assert defaults.get("adversarial_review_level") is not None -def test_resolve_ingredient_defaults_includes_post_run_diagnostics(tmp_path): - """DIAG_C3: resolve_ingredient_defaults includes post_run_diagnostics default false.""" +def test_resolve_ingredient_defaults_includes_pipeline_health(tmp_path): + """DIAG_C3: resolve_ingredient_defaults includes pipeline_health default false.""" from autoskillit.config import resolve_ingredient_defaults repo = tmp_path / "repo" @@ -90,7 +90,7 @@ def test_resolve_ingredient_defaults_includes_post_run_diagnostics(tmp_path): ) defaults = resolve_ingredient_defaults(repo) - assert defaults.get("post_run_diagnostics") == "false" + assert defaults.get("pipeline_health") == "false" def test_resolve_ingredient_defaults_includes_is_fleet_dispatch_false(tmp_path): @@ -183,7 +183,7 @@ def test_resolve_ingredient_defaults_base_branch_from_config(tmp_path): mock_cfg.branching.default_base_branch = "develop" mock_cfg.review.local_review_rounds = 3 mock_cfg.plan.adversarial_review_level = "aggressive" - mock_cfg.diagnostics.post_run_analysis = False + mock_cfg.diagnostics.pipeline_health = False with patch("autoskillit.config.settings.load_config", return_value=mock_cfg): defaults = resolve_ingredient_defaults(repo) @@ -280,16 +280,16 @@ def test_apply_config_authoritative_overrides_unknown_key_retains_caller_value(t # T4: REQ-ING-003 -def test_post_run_diagnostics_not_server_authoritative() -> None: - """post_run_diagnostics must be a config-default, not server-authoritative.""" +def test_pipeline_health_not_server_authoritative() -> None: + """pipeline_health must be a config-default, not server-authoritative.""" from autoskillit.config import SERVER_AUTHORITATIVE_INGREDIENTS - assert "post_run_diagnostics" not in SERVER_AUTHORITATIVE_INGREDIENTS + assert "pipeline_health" not in SERVER_AUTHORITATIVE_INGREDIENTS # T6: REQ-ING-005 -def test_post_run_diagnostics_in_config_default_ingredients() -> None: - """post_run_diagnostics must be in CONFIG_DEFAULT_INGREDIENTS.""" +def test_pipeline_health_in_config_default_ingredients() -> None: + """pipeline_health must be in CONFIG_DEFAULT_INGREDIENTS.""" from autoskillit.config import CONFIG_DEFAULT_INGREDIENTS - assert "post_run_diagnostics" in CONFIG_DEFAULT_INGREDIENTS + assert "pipeline_health" in CONFIG_DEFAULT_INGREDIENTS diff --git a/tests/execution/backends/test_cli_conformance_probes.py b/tests/execution/backends/test_cli_conformance_probes.py index bab432025..2454015b4 100644 --- a/tests/execution/backends/test_cli_conformance_probes.py +++ b/tests/execution/backends/test_cli_conformance_probes.py @@ -938,7 +938,7 @@ def _large_output_prompt(workspace: Path) -> str: '{"task":"test task","issue_url":"https://github.com/test/test/issues/1",' '"is_fleet_dispatch":"true","adversarial_review_level":"true",' '"local_review_rounds":"true","base_branch":"true",' - '"post_run_diagnostics":"true"}. Then make every autoskillit run_cmd call below, ' + '"pipeline_health":"true"}. Then make every autoskillit run_cmd call below, ' "in order. Do not substitute native shell tools and do not omit a call.\n" f"{calls}\nAfter all calls, respond with exactly: probe-complete" ) diff --git a/tests/infra/test_pretty_output_recipe.py b/tests/infra/test_pretty_output_recipe.py index 1f9e73b82..bd395cb17 100644 --- a/tests/infra/test_pretty_output_recipe.py +++ b/tests/infra/test_pretty_output_recipe.py @@ -916,7 +916,7 @@ def _strip_presentation_fields(parsed: dict) -> dict: "adversarial_review_level": "true", "local_review_rounds": "true", "base_branch": "true", - "post_run_diagnostics": "true", + "pipeline_health": "true", }, } diff --git a/tests/recipe/test_bundled_recipes_all_truthy.py b/tests/recipe/test_bundled_recipes_all_truthy.py index dc9e02932..580f4e534 100644 --- a/tests/recipe/test_bundled_recipes_all_truthy.py +++ b/tests/recipe/test_bundled_recipes_all_truthy.py @@ -26,7 +26,7 @@ "adversarial_review_level": "true", "local_review_rounds": "true", "base_branch": "true", - "post_run_diagnostics": "true", + "pipeline_health": "true", } diff --git a/tests/recipe/test_bundled_recipes_general.py b/tests/recipe/test_bundled_recipes_general.py index fcc25d693..880d872c9 100644 --- a/tests/recipe/test_bundled_recipes_general.py +++ b/tests/recipe/test_bundled_recipes_general.py @@ -684,18 +684,18 @@ def test_recipe_has_unconditional_register_steps(recipe_name: str) -> None: assert "register_clone_failure" in recipe.steps s = recipe.steps["register_clone_success"] f = recipe.steps["register_clone_failure"] - # Accept direct routing to done/escalate_stop OR indirect via optional run_diagnostic steps - assert s.on_success in ("done", "run_diagnostic"), ( - "register_clone_success.on_success must route to done or run_diagnostic, " + # Accept direct routing to done/escalate_stop OR indirect via optional pipeline_health steps + assert s.on_success in ("done", "pipeline_health"), ( + "register_clone_success.on_success must route to done or pipeline_health, " f"got {s.on_success!r}" ) - assert f.on_success in ("escalate_stop", "run_diagnostic_error"), ( + assert f.on_success in ("escalate_stop", "pipeline_health_error"), ( "register_clone_failure.on_success must route to escalate_stop or " - f"run_diagnostic_error, got {f.on_success!r}" + f"pipeline_health_error, got {f.on_success!r}" ) - assert f.on_failure in ("escalate_stop", "run_diagnostic_error"), ( + assert f.on_failure in ("escalate_stop", "pipeline_health_error"), ( "register_clone_failure.on_failure must route to escalate_stop or " - f"run_diagnostic_error, got {f.on_failure!r}" + f"pipeline_health_error, got {f.on_failure!r}" ) assert "check_defer_cleanup" not in recipe.steps assert "check_defer_on_failure" not in recipe.steps diff --git a/tests/recipe/test_check_ci_already_passed_routing.py b/tests/recipe/test_check_ci_already_passed_routing.py index 3e7ed8e15..f0682de42 100644 --- a/tests/recipe/test_check_ci_already_passed_routing.py +++ b/tests/recipe/test_check_ci_already_passed_routing.py @@ -90,7 +90,7 @@ def test_no_direct_escalate_stop_no_ci_callers_except_safety_net(recipe): "escalate_stop_no_ci", "mark_issue_failed_no_ci", "register_clone_no_ci", - "run_diagnostic_no_ci", + "pipeline_health_no_ci", } for name, step in recipe.steps.items(): if name in EXCLUDED: @@ -116,14 +116,14 @@ def test_register_clone_no_ci_routes_to_escalate_stop_no_ci(recipe): """register_clone_no_ci registers clone as error and routes toward escalate_stop_no_ci.""" step = recipe.steps["register_clone_no_ci"] assert step.tool == "register_clone_status" - # May route via optional run_diagnostic_no_ci step first - assert step.on_success in ("escalate_stop_no_ci", "run_diagnostic_no_ci"), ( + # May route via optional pipeline_health_no_ci step first + assert step.on_success in ("escalate_stop_no_ci", "pipeline_health_no_ci"), ( "register_clone_no_ci.on_success must route to escalate_stop_no_ci " - f"or run_diagnostic_no_ci, got {step.on_success!r}" + f"or pipeline_health_no_ci, got {step.on_success!r}" ) - assert step.on_failure in ("escalate_stop_no_ci", "run_diagnostic_no_ci"), ( + assert step.on_failure in ("escalate_stop_no_ci", "pipeline_health_no_ci"), ( "register_clone_no_ci.on_failure must route to escalate_stop_no_ci " - f"or run_diagnostic_no_ci, got {step.on_failure!r}" + f"or pipeline_health_no_ci, got {step.on_failure!r}" ) assert step.with_args.get("status") == "error" @@ -139,8 +139,8 @@ def test_no_ci_failure_chain_complete(recipe): assert mark_step.on_success == "register_clone_no_ci" reg_step = recipe.steps["register_clone_no_ci"] - # May route via optional run_diagnostic_no_ci step that then routes to escalate_stop_no_ci - assert reg_step.on_success in ("escalate_stop_no_ci", "run_diagnostic_no_ci"), ( + # May route via optional pipeline_health_no_ci step that then routes to escalate_stop_no_ci + assert reg_step.on_success in ("escalate_stop_no_ci", "pipeline_health_no_ci"), ( "register_clone_no_ci.on_success must route toward escalate_stop_no_ci, " f"got {reg_step.on_success!r}" ) diff --git a/tests/recipe/test_diagnostic_steps.py b/tests/recipe/test_diagnostic_steps.py index d285e0b2c..3b1af1f85 100644 --- a/tests/recipe/test_diagnostic_steps.py +++ b/tests/recipe/test_diagnostic_steps.py @@ -39,24 +39,24 @@ def test_analyze_pipeline_health_coordinator_validates_scanners(): ) -# DIAG_C9: run_diagnostic steps have required fields in implementation recipe +# DIAG_C9: pipeline_health steps have required fields in implementation recipe @pytest.mark.parametrize("recipe_name", ["implementation", "remediation", "merge-prs"]) -def test_run_diagnostic_steps_have_required_fields(recipe_name): - """run_diagnostic steps must have on_context_limit, optional=true, skip_when_false.""" +def test_pipeline_health_steps_have_required_fields(recipe_name): + """pipeline_health steps must have on_context_limit, optional=true, skip_when_false.""" recipe = load_recipe(builtin_recipes_dir() / f"{recipe_name}.yaml") for name, step in recipe.steps.items(): - if name.startswith("run_diagnostic"): + if name.startswith("pipeline_health"): assert step.on_context_limit is not None, f"{name} missing on_context_limit" assert step.optional is True, f"{name} optional must be True" - assert step.skip_when_false == "inputs.post_run_diagnostics", ( - f"{name} skip_when_false must be inputs.post_run_diagnostics" + assert step.skip_when_false == "inputs.pipeline_health", ( + f"{name} skip_when_false must be inputs.pipeline_health" ) # T7: REQ-TEST-004 def test_implementation_family_recipes_route_terminals_through_diagnostics() -> None: """REQ-TEST-004: Every register_clone_* terminal in implementation-family recipes - routes through a run_diagnostic* step gated on post_run_diagnostics.""" + routes through a pipeline_health* step gated on pipeline_health.""" recipes_dir = builtin_recipes_dir() target_names = ["implementation.yaml", "implementation-groups.yaml"] missing: list[str] = [] @@ -66,8 +66,8 @@ def test_implementation_family_recipes_route_terminals_through_diagnostics() -> missing.append(name) assert not missing, f"Recipe files not found: {missing}" - diag_step_prefixes = ("run_diagnostic",) - required_post_run_refs = ("inputs.post_run_diagnostics",) + diag_step_prefixes = ("pipeline_health",) + required_post_run_refs = ("inputs.pipeline_health",) for name in target_names: recipe_path = recipes_dir / name @@ -76,14 +76,14 @@ def test_implementation_family_recipes_route_terminals_through_diagnostics() -> clone_steps = [(n, s) for n, s in steps.items() if n.startswith("register_clone_")] assert clone_steps, f"{name}: expected at least one register_clone_* step" for step_name, cs in clone_steps: - # The step must route on_success to a run_diagnostic* step + # The step must route on_success to a pipeline_health* step next_step = cs.on_success assert next_step is not None, f"{name}: {step_name} has no on_success" assert next_step.startswith(diag_step_prefixes), ( f"{name}: {step_name}.on_success={next_step!r} must start with " f"{diag_step_prefixes!r}" ) - # The run_diagnostic* step must gate on inputs.post_run_diagnostics + # The pipeline_health* step must gate on inputs.pipeline_health diag = steps.get(next_step) assert diag is not None, ( f"{name}: step {step_name} routes to {next_step!r} but no such step exists" diff --git a/tests/recipe/test_hidden_ingredients.py b/tests/recipe/test_hidden_ingredients.py index fc7aa2ca7..7123d8954 100644 --- a/tests/recipe/test_hidden_ingredients.py +++ b/tests/recipe/test_hidden_ingredients.py @@ -128,7 +128,7 @@ def test_prune_skipped_steps_truthy_clears_field() -> None: name="test", description="test", ingredients={ - "post_run_diagnostics": RecipeIngredient( + "pipeline_health": RecipeIngredient( description="Enable post-run diagnostics", default="false", hidden=True, @@ -141,7 +141,7 @@ def test_prune_skipped_steps_truthy_clears_field() -> None: "diag": RecipeStep( tool="run_skill", optional=True, - skip_when_false="inputs.post_run_diagnostics", + skip_when_false="inputs.pipeline_health", on_success="done", on_failure="done", with_args={"skill_command": "/autoskillit:diagnose /tmp/x.md", "cwd": "/tmp"}, @@ -152,14 +152,14 @@ def test_prune_skipped_steps_truthy_clears_field() -> None: ) pruned, resolutions = _prune_skipped_steps( - recipe, ingredient_overrides={"post_run_diagnostics": "true"} + recipe, ingredient_overrides={"pipeline_health": "true"} ) assert "diag" in pruned.steps assert pruned.steps["diag"].skip_when_false is None assert resolutions["diag"] is True pruned2, resolutions2 = _prune_skipped_steps( - recipe, ingredient_overrides={"post_run_diagnostics": "false"} + recipe, ingredient_overrides={"pipeline_health": "false"} ) assert "diag" not in pruned2.steps assert resolutions2["diag"] is False @@ -173,7 +173,7 @@ def test_prune_skipped_steps_removes_step_and_cleans_routes() -> None: name="test", description="test", ingredients={ - "post_run_diagnostics": RecipeIngredient( + "pipeline_health": RecipeIngredient( description="Enable diagnostics", default="false", hidden=True, @@ -186,7 +186,7 @@ def test_prune_skipped_steps_removes_step_and_cleans_routes() -> None: "diag": RecipeStep( tool="run_skill", optional=True, - skip_when_false="inputs.post_run_diagnostics", + skip_when_false="inputs.pipeline_health", on_success="done", on_failure="done", with_args={"skill_command": "/autoskillit:diagnose /tmp/x.md", "cwd": "/tmp"}, @@ -196,9 +196,7 @@ def test_prune_skipped_steps_removes_step_and_cleans_routes() -> None: kitchen_rules=["test"], ) - pruned, _ = _prune_skipped_steps( - recipe, ingredient_overrides={"post_run_diagnostics": "false"} - ) + pruned, _ = _prune_skipped_steps(recipe, ingredient_overrides={"pipeline_health": "false"}) assert "diag" not in pruned.steps # Route repaired: upstream.on_success now points to diag's on_success (done) assert pruned.steps["upstream"].on_success == "done" @@ -392,7 +390,7 @@ def test_load_and_validate_resolves_skip_guards_in_content(tmp_path: Path) -> No kitchen_rules: - no native tools ingredients: - post_run_diagnostics: + pipeline_health: description: Enable diagnostics default: "false" hidden: true @@ -405,7 +403,7 @@ def test_load_and_validate_resolves_skip_guards_in_content(tmp_path: Path) -> No diag: tool: run_skill optional: true - skip_when_false: inputs.post_run_diagnostics + skip_when_false: inputs.pipeline_health with: skill_command: /autoskillit:diagnose /tmp/x.md cwd: /tmp @@ -422,9 +420,9 @@ def test_load_and_validate_resolves_skip_guards_in_content(tmp_path: Path) -> No result = load_and_validate( "test-skip-guards", project_dir=tmp_path, - ingredient_overrides={"post_run_diagnostics": "true"}, + ingredient_overrides={"pipeline_health": "true"}, ) - assert "inputs.post_run_diagnostics" not in result["content"] + assert "inputs.pipeline_health" not in result["content"] content = result["content"] diag_block_start = content.index(" diag:\n") next_step_start = content.find("\n done:\n", diag_block_start) @@ -435,9 +433,9 @@ def test_load_and_validate_resolves_skip_guards_in_content(tmp_path: Path) -> No result2 = load_and_validate( "test-skip-guards", project_dir=tmp_path, - ingredient_overrides={"post_run_diagnostics": "false"}, + ingredient_overrides={"pipeline_health": "false"}, ) - assert "inputs.post_run_diagnostics" not in result2["content"] + assert "inputs.pipeline_health" not in result2["content"] assert 'skip_when_false: "false"' not in result2["content"] assert " diag:\n" not in result2["content"] diff --git a/tests/recipe/test_implementation.py b/tests/recipe/test_implementation.py index e6deea73b..8b4855343 100644 --- a/tests/recipe/test_implementation.py +++ b/tests/recipe/test_implementation.py @@ -244,28 +244,28 @@ def test_done_already_done_stop_exists(recipe) -> None: def test_register_clone_no_changes_routes_to_diagnostic(recipe) -> None: - """register_clone_no_changes must route to run_diagnostic_no_changes.""" + """register_clone_no_changes must route to pipeline_health_no_changes.""" assert "register_clone_no_changes" in recipe.steps step = recipe.steps["register_clone_no_changes"] - assert step.on_success == "run_diagnostic_no_changes" + assert step.on_success == "pipeline_health_no_changes" def test_register_clone_already_done_routes_to_diagnostic(recipe) -> None: - """register_clone_already_done must route to run_diagnostic_already_done.""" + """register_clone_already_done must route to pipeline_health_already_done.""" assert "register_clone_already_done" in recipe.steps step = recipe.steps["register_clone_already_done"] - assert step.on_success == "run_diagnostic_already_done" + assert step.on_success == "pipeline_health_already_done" def test_register_clone_unconfirmed_routes_to_done_unconfirmed(recipe) -> None: """register_clone_unconfirmed must route toward done_unconfirmed.""" step = recipe.steps["register_clone_unconfirmed"] - # May route via optional run_diagnostic_unconfirmed step first - assert step.on_success in ("done_unconfirmed", "run_diagnostic_unconfirmed"), ( + # May route via optional pipeline_health_unconfirmed step first + assert step.on_success in ("done_unconfirmed", "pipeline_health_unconfirmed"), ( "register_clone_unconfirmed.on_success must route toward done_unconfirmed, " f"got {step.on_success!r}" ) - assert step.on_failure in ("done_unconfirmed", "run_diagnostic_unconfirmed"), ( + assert step.on_failure in ("done_unconfirmed", "pipeline_health_unconfirmed"), ( "register_clone_unconfirmed.on_failure must route toward done_unconfirmed, " f"got {step.on_failure!r}" ) diff --git a/tests/recipe/test_implementation_groups_pr_decomposition.py b/tests/recipe/test_implementation_groups_pr_decomposition.py index a2218caa4..6f793e753 100644 --- a/tests/recipe/test_implementation_groups_pr_decomposition.py +++ b/tests/recipe/test_implementation_groups_pr_decomposition.py @@ -68,7 +68,7 @@ def test_done_unconfirmed_stop_exists(recipe) -> None: def test_register_clone_unconfirmed_routes_to_done_unconfirmed(recipe) -> None: - """register_clone_unconfirmed must route to run_diagnostic_unconfirmed.""" + """register_clone_unconfirmed must route to pipeline_health_unconfirmed.""" step = recipe.steps["register_clone_unconfirmed"] - assert step.on_success == "run_diagnostic_unconfirmed" - assert step.on_failure == "run_diagnostic_unconfirmed" + assert step.on_success == "pipeline_health_unconfirmed" + assert step.on_failure == "pipeline_health_unconfirmed" diff --git a/tests/recipe/test_remediation_recipe.py b/tests/recipe/test_remediation_recipe.py index 717c81663..9aaacf0b9 100644 --- a/tests/recipe/test_remediation_recipe.py +++ b/tests/recipe/test_remediation_recipe.py @@ -251,28 +251,28 @@ def test_done_already_done_stop_exists(recipe) -> None: def test_register_clone_no_changes_routes_to_diagnostic(recipe) -> None: - """register_clone_no_changes must route to run_diagnostic_no_changes.""" + """register_clone_no_changes must route to pipeline_health_no_changes.""" assert "register_clone_no_changes" in recipe.steps step = recipe.steps["register_clone_no_changes"] - assert step.on_success == "run_diagnostic_no_changes" + assert step.on_success == "pipeline_health_no_changes" def test_register_clone_already_done_routes_to_diagnostic(recipe) -> None: - """register_clone_already_done must route to run_diagnostic_already_done.""" + """register_clone_already_done must route to pipeline_health_already_done.""" assert "register_clone_already_done" in recipe.steps step = recipe.steps["register_clone_already_done"] - assert step.on_success == "run_diagnostic_already_done" + assert step.on_success == "pipeline_health_already_done" def test_register_clone_unconfirmed_routes_to_done_unconfirmed(recipe) -> None: """register_clone_unconfirmed must route toward done_unconfirmed.""" step = recipe.steps["register_clone_unconfirmed"] - # May route via optional run_diagnostic_unconfirmed step first - assert step.on_success in ("done_unconfirmed", "run_diagnostic_unconfirmed"), ( + # May route via optional pipeline_health_unconfirmed step first + assert step.on_success in ("done_unconfirmed", "pipeline_health_unconfirmed"), ( "register_clone_unconfirmed.on_success must route toward done_unconfirmed, " f"got {step.on_success!r}" ) - assert step.on_failure in ("done_unconfirmed", "run_diagnostic_unconfirmed"), ( + assert step.on_failure in ("done_unconfirmed", "pipeline_health_unconfirmed"), ( "register_clone_unconfirmed.on_failure must route toward done_unconfirmed, " f"got {step.on_failure!r}" ) diff --git a/tests/server/_helpers.py b/tests/server/_helpers.py index 9cb49aeab..e83a9886a 100644 --- a/tests/server/_helpers.py +++ b/tests/server/_helpers.py @@ -106,7 +106,7 @@ def _skill_fail() -> SkillResult: "adversarial_review_level": "aggressive", "is_fleet_dispatch": "true", "dispatch_id": "test-dispatch-999", - "post_run_diagnostics": "true", + "pipeline_health": "true", } _SERVER_ONLY_KEYS = frozenset({"kitchen_id", "diagnostics_log_dir", "backend_supports_git_write"}) diff --git a/tests/server/test_lock_ingredients.py b/tests/server/test_lock_ingredients.py index 89ab72ea8..0462cc062 100644 --- a/tests/server/test_lock_ingredients.py +++ b/tests/server/test_lock_ingredients.py @@ -490,8 +490,8 @@ async def call_lock(pipeline_id: str) -> None: # T3: REQ-ING-004 @pytest.mark.anyio -async def test_post_run_diagnostics_lockable(tmp_path): - """REQ-ING-004: lock_ingredients accepts post_run_diagnostics.""" +async def test_pipeline_health_lockable(tmp_path): + """REQ-ING-004: lock_ingredients accepts pipeline_health.""" temp_dir = tmp_path / ".autoskillit" / "temp" temp_dir.mkdir(parents=True) (temp_dir / ".hook_config.json").write_text("{}") @@ -503,11 +503,7 @@ async def test_post_run_diagnostics_lockable(tmp_path): with patch("autoskillit.server._get_ctx", return_value=ctx): from autoskillit.server.tools.tools_kitchen import lock_ingredients - result_str = await lock_ingredients( - locked={"post_run_diagnostics": "true"}, pipeline_id="a" - ) + result_str = await lock_ingredients(locked={"pipeline_health": "true"}, pipeline_id="a") result = json.loads(result_str) - assert result.get("success") is True, ( - f"post_run_diagnostics must be lockable; got result={result}" - ) + assert result.get("success") is True, f"pipeline_health must be lockable; got result={result}" diff --git a/tests/server/test_mcp_overrides.py b/tests/server/test_mcp_overrides.py index 75a0405a7..dd63a3f77 100644 --- a/tests/server/test_mcp_overrides.py +++ b/tests/server/test_mcp_overrides.py @@ -64,7 +64,7 @@ async def test_load_recipe_tool_accepts_overrides_param(tmp_path: Path) -> None: assert result.get("valid") is True # Verify user-supplied overrides were passed through to load_and_validate - # (merged with auto-injected kitchen_id and post_run_diagnostics) + # (merged with auto-injected kitchen_id and pipeline_health) mock_recipes.load_and_validate.assert_called_once() call_kwargs = mock_recipes.load_and_validate.call_args actual_overrides = call_kwargs.kwargs.get("ingredient_overrides") or {} @@ -121,7 +121,7 @@ async def test_open_kitchen_accepts_overrides_param(tmp_path: Path) -> None: assert result.get("valid") is True # Verify user-supplied overrides were passed through to load_and_validate - # (merged with auto-injected kitchen_id and post_run_diagnostics) + # (merged with auto-injected kitchen_id and pipeline_health) mock_recipes.load_and_validate.assert_called_once() call_kwargs = mock_recipes.load_and_validate.call_args actual_overrides = call_kwargs.kwargs.get("ingredient_overrides") or {} diff --git a/tests/server/test_tools_kitchen_envelope.py b/tests/server/test_tools_kitchen_envelope.py index e9d8b1ee6..60e29d685 100644 --- a/tests/server/test_tools_kitchen_envelope.py +++ b/tests/server/test_tools_kitchen_envelope.py @@ -444,7 +444,7 @@ async def test_open_kitchen_config_authority_overrides_caller(tmp_path, monkeypa "autoskillit.server.tools.tools_kitchen.resolve_ingredient_defaults", return_value={ "base_branch": "develop", - "post_run_diagnostics": "false", + "pipeline_health": "false", "is_fleet_dispatch": "false", "dispatch_id": "", }, @@ -538,7 +538,7 @@ async def test_open_kitchen_with_config_authority_ingredient(monkeypatch): "autoskillit.server.tools.tools_kitchen.resolve_ingredient_defaults", lambda _: { "base_branch": "develop", - "post_run_diagnostics": "false", + "pipeline_health": "false", "is_fleet_dispatch": "false", "dispatch_id": "", }, @@ -1095,21 +1095,21 @@ def test_recipe_validation_error_response_handles_malformed_suggestions(): # --------------------------------------------------------------------------- -# post_run_diagnostics demotion tests (T1, T2, T5) +# pipeline_health demotion tests (T1, T2, T5) # --------------------------------------------------------------------------- # T1: REQ-ING-001 @pytest.mark.anyio -async def test_post_run_diagnostics_override_wins_over_config(tmp_path, monkeypatch): - """REQ-ING-001: open_kitchen override for post_run_diagnostics wins over config.""" +async def test_pipeline_health_override_wins_over_config(tmp_path, monkeypatch): + """REQ-ING-001: open_kitchen override for pipeline_health wins over config.""" monkeypatch.chdir(tmp_path) mock_ctx = _make_mock_ctx() mock_ctx.enable_components = AsyncMock() mock_ctx.recipes = MagicMock() mock_recipe_obj = MagicMock() mock_recipe_obj.steps = {"do": MagicMock()} - mock_recipe_obj.ingredients = {"post_run_diagnostics": MagicMock()} + mock_recipe_obj.ingredients = {"pipeline_health": MagicMock()} mock_ctx.recipes.load.return_value = mock_recipe_obj mock_ctx.recipes.load_and_validate.return_value = { "content": "name: demo\nsteps:\n do:\n tool: run_cmd\n", @@ -1139,7 +1139,7 @@ async def test_post_run_diagnostics_override_wins_over_config(tmp_path, monkeypa "autoskillit.server.tools.tools_kitchen.resolve_ingredient_defaults", return_value={ "base_branch": "develop", - "post_run_diagnostics": "false", + "pipeline_health": "false", "is_fleet_dispatch": "false", "dispatch_id": "", }, @@ -1148,22 +1148,20 @@ async def test_post_run_diagnostics_override_wins_over_config(tmp_path, monkeypa await open_kitchen( name="demo", - overrides={"post_run_diagnostics": "true"}, + overrides={"pipeline_health": "true"}, ctx=mock_ctx, ) call_kwargs = mock_ctx.recipes.load_and_validate.call_args.kwargs overrides = call_kwargs["ingredient_overrides"] - assert overrides["post_run_diagnostics"] == "true", ( - f"Override must win; got overrides={overrides}" - ) + assert overrides["pipeline_health"] == "true", f"Override must win; got overrides={overrides}" call_args_list = mock_ctx.recipes.load_and_validate.call_args_list assert call_args_list, "open_kitchen should call load_and_validate" # T2: REQ-ING-002 @pytest.mark.anyio -async def test_post_run_diagnostics_config_default_applied(tmp_path, monkeypatch): +async def test_pipeline_health_config_default_applied(tmp_path, monkeypatch): """REQ-ING-002: Without override, config value is used as default.""" monkeypatch.chdir(tmp_path) mock_ctx = _make_mock_ctx() @@ -1171,7 +1169,7 @@ async def test_post_run_diagnostics_config_default_applied(tmp_path, monkeypatch mock_ctx.recipes = MagicMock() mock_recipe_obj = MagicMock() mock_recipe_obj.steps = {"do": MagicMock()} - mock_recipe_obj.ingredients = {"post_run_diagnostics": MagicMock()} + mock_recipe_obj.ingredients = {"pipeline_health": MagicMock()} mock_ctx.recipes.load.return_value = mock_recipe_obj mock_ctx.recipes.load_and_validate.return_value = { "content": "name: demo\nsteps:\n do:\n tool: run_cmd\n", @@ -1201,7 +1199,7 @@ async def test_post_run_diagnostics_config_default_applied(tmp_path, monkeypatch "autoskillit.server.tools.tools_kitchen.resolve_ingredient_defaults", return_value={ "base_branch": "develop", - "post_run_diagnostics": "true", + "pipeline_health": "true", "is_fleet_dispatch": "false", "dispatch_id": "", }, @@ -1212,7 +1210,7 @@ async def test_post_run_diagnostics_config_default_applied(tmp_path, monkeypatch call_kwargs = mock_ctx.recipes.load_and_validate.call_args.kwargs overrides = call_kwargs["ingredient_overrides"] - assert overrides["post_run_diagnostics"] == "true", ( + assert overrides["pipeline_health"] == "true", ( f"Config default must apply; got overrides={overrides}" ) From e1c86f034b78e43311f4ccbb6783a0a323453582 Mon Sep 17 00:00:00 2001 From: Trecek Date: Mon, 20 Jul 2026 08:20:02 -0700 Subject: [PATCH 04/10] rename: pipeline health developer documentation references MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit docs/developer/diagnostics.md lines 91-97 updated to use the canonical pipeline_health token in the per-run enablement section. The example overrides, lock_ingredients snippet, and config field name now match the renamed surface (diagnostics.pipeline_health config field, the pipeline_health ingredient, the pipeline_health routing targets). The skill directory reference (/autoskillit:analyze-pipeline-health) is unchanged — the canonical token pipeline-health already appears in the directory name and the rename provides no discoverability gain. Co-Authored-By: Claude --- docs/developer/diagnostics.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/developer/diagnostics.md b/docs/developer/diagnostics.md index 5b723ae57..1a15884d4 100644 --- a/docs/developer/diagnostics.md +++ b/docs/developer/diagnostics.md @@ -88,13 +88,13 @@ linux_tracing: ## Per-Run Enablement -By default, `post_run_diagnostics` resolves from `diagnostics.post_run_analysis` (shipped +By default, `pipeline_health` resolves from `diagnostics.pipeline_health` (shipped default: `false`). To enable diagnostics for a single run, the orchestrator can pass -`overrides={"post_run_diagnostics": "true"}` to `open_kitchen`. The override takes effect +`overrides={"pipeline_health": "true"}` to `open_kitchen`. The override takes effect for that kitchen session only and does not modify the persistent config. The orchestrator can also lock the value for the session via -`lock_ingredients(locked={"post_run_diagnostics": "true"})` to ensure it is not overridden +`lock_ingredients(locked={"pipeline_health": "true"})` to ensure it is not overridden by downstream steps. For post-hoc diagnostics on a completed run, use: From 16afef492b32cd314a497c6e47dc889cffdac0fa Mon Sep 17 00:00:00 2001 From: Trecek Date: Mon, 20 Jul 2026 08:34:53 -0700 Subject: [PATCH 05/10] fix: refresh diagram hashes, golden ceiling, and sigterm test HOME isolation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pipeline_health naming rename (post_run_diagnostics -> pipeline_health) changed rendered recipe payload sizes and recipe-file hashes without the plan accounting for these downstream test dependents: - Recipe diagram staleness hashes for implementation, implementation-groups, merge-prs, and remediation are recomputed from the renamed YAML content. Diagram bodies are unchanged since the diagnostics step is hidden infrastructure in the rendered flow. - The pinned byte-size ceiling in test_canonical_recipe_responses_fit_independent_registry_ceilings is updated to the new measured remediation/all_truthy payload size. - test_sigterm_writes_scenario_json now isolates HOME for its subprocess so it does not load the developer's real ~/.autoskillit/config.yaml, which can contain stale pre-rename keys and fail schema validation — following the same isolation pattern used by other subprocess tests in this suite. --- .../recipes/diagrams/implementation-groups.md | 2 +- src/autoskillit/recipes/diagrams/implementation.md | 2 +- src/autoskillit/recipes/diagrams/merge-prs.md | 2 +- src/autoskillit/recipes/diagrams/remediation.md | 2 +- tests/execution/test_recording_sigterm.py | 11 ++++++++--- tests/infra/test_pretty_output_recipe.py | 4 ++-- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/autoskillit/recipes/diagrams/implementation-groups.md b/src/autoskillit/recipes/diagrams/implementation-groups.md index 8a66dd7ac..2fca940c7 100644 --- a/src/autoskillit/recipes/diagrams/implementation-groups.md +++ b/src/autoskillit/recipes/diagrams/implementation-groups.md @@ -1,4 +1,4 @@ - + ## implementation-groups diff --git a/src/autoskillit/recipes/diagrams/implementation.md b/src/autoskillit/recipes/diagrams/implementation.md index 6002f8423..ba2fa9fbe 100644 --- a/src/autoskillit/recipes/diagrams/implementation.md +++ b/src/autoskillit/recipes/diagrams/implementation.md @@ -1,4 +1,4 @@ - + ## implementation diff --git a/src/autoskillit/recipes/diagrams/merge-prs.md b/src/autoskillit/recipes/diagrams/merge-prs.md index 28a355200..e7b5ce42c 100644 --- a/src/autoskillit/recipes/diagrams/merge-prs.md +++ b/src/autoskillit/recipes/diagrams/merge-prs.md @@ -1,4 +1,4 @@ - + ## merge-prs Merge multiple PRs into an integration branch with conflict resolution and CI gates. diff --git a/src/autoskillit/recipes/diagrams/remediation.md b/src/autoskillit/recipes/diagrams/remediation.md index 56ef04f67..a9c5b4510 100644 --- a/src/autoskillit/recipes/diagrams/remediation.md +++ b/src/autoskillit/recipes/diagrams/remediation.md @@ -1,4 +1,4 @@ - + ## remediation diff --git a/tests/execution/test_recording_sigterm.py b/tests/execution/test_recording_sigterm.py index 8d146d5c5..24460dd1f 100644 --- a/tests/execution/test_recording_sigterm.py +++ b/tests/execution/test_recording_sigterm.py @@ -33,6 +33,8 @@ def test_sigterm_writes_scenario_json(tmp_path): output_dir.mkdir() state_dir = tmp_path / "state" state_dir.mkdir() + home_dir = tmp_path / "home" + home_dir.mkdir() env = { **os.environ, @@ -40,12 +42,15 @@ def test_sigterm_writes_scenario_json(tmp_path): "RECORD_SCENARIO_DIR": str(output_dir), "RECORD_SCENARIO_RECIPE": "test-recipe", "AUTOSKILLIT_STATE_DIR": str(state_dir), + "HOME": str(home_dir), } # Use sys.executable -m to ensure we run the worktree-installed version, # not a system-wide `autoskillit` binary that may lack the lifespan fix. - # cwd=tmp_path and AUTOSKILLIT_STATE_DIR isolate the subprocess's - # filesystem state from the project tree (e.g. any real execution - # markers under CWD) so the sentinel location is deterministic. + # cwd=tmp_path, AUTOSKILLIT_STATE_DIR, and HOME isolate the subprocess's + # filesystem state from the project tree and the developer's real + # ~/.autoskillit/config.yaml (e.g. any real execution markers under CWD, + # or stale config keys from a prior schema) so the sentinel location and + # config layers are deterministic. proc = subprocess.Popen( [sys.executable, "-m", "autoskillit"], stdin=subprocess.PIPE, diff --git a/tests/infra/test_pretty_output_recipe.py b/tests/infra/test_pretty_output_recipe.py index bd395cb17..3cdb14bd7 100644 --- a/tests/infra/test_pretty_output_recipe.py +++ b/tests/infra/test_pretty_output_recipe.py @@ -1052,8 +1052,8 @@ def test_canonical_recipe_responses_fit_independent_registry_ceilings(tmp_path, for ingredients_only in (False, True) } assert maxima == { - "load_recipe": (182_759, "remediation", "all_truthy"), - "open_kitchen": (182_818, "remediation", "all_truthy"), + "load_recipe": (182_956, "remediation", "all_truthy"), + "open_kitchen": (183_015, "remediation", "all_truthy"), } From 84c7dec7022165ba1e4ec8e2a5fa73fe28a9f352 Mon Sep 17 00:00:00 2001 From: Trecek Date: Mon, 20 Jul 2026 08:38:59 -0700 Subject: [PATCH 06/10] fix: correct golden ceiling after diagram staleness fix removed noise MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prior fix's golden values (182_956/183_015) were measured while the remediation diagram was still stale, so the served payload included an extra "stale diagram" suggestion inflating the byte count. Now that the diagram hash is fresh, the payload is smaller — re-pin to the actual measured size (182_796/182_855). --- tests/infra/test_pretty_output_recipe.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/infra/test_pretty_output_recipe.py b/tests/infra/test_pretty_output_recipe.py index 3cdb14bd7..ac70098d8 100644 --- a/tests/infra/test_pretty_output_recipe.py +++ b/tests/infra/test_pretty_output_recipe.py @@ -1052,8 +1052,8 @@ def test_canonical_recipe_responses_fit_independent_registry_ceilings(tmp_path, for ingredients_only in (False, True) } assert maxima == { - "load_recipe": (182_956, "remediation", "all_truthy"), - "open_kitchen": (183_015, "remediation", "all_truthy"), + "load_recipe": (182_796, "remediation", "all_truthy"), + "open_kitchen": (182_855, "remediation", "all_truthy"), } From 421602423efc7240f7bfcf9252f2af63975e7547 Mon Sep 17 00:00:00 2001 From: Trecek Date: Mon, 20 Jul 2026 09:32:20 -0700 Subject: [PATCH 07/10] fix(review): add pipeline health config migration note --- .../migrations/0.10.884-to-0.10.885.yaml | 27 +++++++++++++++++++ tests/migration/AGENTS.md | 1 + .../test_pipeline_health_migration_note.py | 25 +++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 src/autoskillit/migrations/0.10.884-to-0.10.885.yaml create mode 100644 tests/migration/test_pipeline_health_migration_note.py diff --git a/src/autoskillit/migrations/0.10.884-to-0.10.885.yaml b/src/autoskillit/migrations/0.10.884-to-0.10.885.yaml new file mode 100644 index 000000000..30ba4e531 --- /dev/null +++ b/src/autoskillit/migrations/0.10.884-to-0.10.885.yaml @@ -0,0 +1,27 @@ +from_version: "0.10.884" +to_version: "0.10.885" +description: > + Diagnostics configuration rename: diagnostics.post_run_analysis is now + diagnostics.pipeline_health. +changes: + - id: diagnostics-post-run-analysis-to-pipeline-health + description: > + The diagnostics.post_run_analysis config key has been renamed to + diagnostics.pipeline_health. The value and default behavior are unchanged. + instruction: | + In your user or project .autoskillit/config.yaml, replace: + diagnostics: + post_run_analysis: true + with: + diagnostics: + pipeline_health: true + Preserve the configured boolean value. The old 'post_run_analysis' key is + no longer recognized and will raise a ConfigSchemaError at startup. + detect: + key: diagnostics.post_run_analysis + example_before: | + diagnostics: + post_run_analysis: true + example_after: | + diagnostics: + pipeline_health: true diff --git a/tests/migration/AGENTS.md b/tests/migration/AGENTS.md index 7bea21fd2..08596c28b 100644 --- a/tests/migration/AGENTS.md +++ b/tests/migration/AGENTS.md @@ -12,5 +12,6 @@ Migration engine, store, and loader tests. | `test_engine.py` | Tests for migration_engine.py — ME1 through ME21 | | `test_fleet_migration_note.py` | Fleet migration note tests | | `test_loader.py` | Tests for migration note discovery and version chaining | +| `test_pipeline_health_migration_note.py` | Diagnostics config-key rename migration note tests | | `test_store.py` | Tests for failure_store.py — FS1 through FS11 and FS-IM1 through FS-IM4 | | `test_vis_lens_rename_migration_note.py` | Vis-lens skill rename migration note tests | diff --git a/tests/migration/test_pipeline_health_migration_note.py b/tests/migration/test_pipeline_health_migration_note.py new file mode 100644 index 000000000..684bf7dcf --- /dev/null +++ b/tests/migration/test_pipeline_health_migration_note.py @@ -0,0 +1,25 @@ +"""Tests for the diagnostics pipeline-health config migration note.""" + +import pytest + +from autoskillit.core import load_yaml, pkg_root + +pytestmark = [pytest.mark.layer("migration"), pytest.mark.small] + + +def test_pipeline_health_config_rename_has_migration_note() -> None: + """The persisted diagnostics key rename must have actionable migration guidance.""" + note_path = pkg_root() / "migrations" / "0.10.884-to-0.10.885.yaml" + note = load_yaml(note_path) + changes = note["changes"] + change = next( + item + for item in changes + if item.get("detect", {}).get("key") == "diagnostics.post_run_analysis" + ) + + assert note["from_version"] == "0.10.884" + assert note["to_version"] == "0.10.885" + assert change["instruction"].strip() + assert "post_run_analysis" in change["example_before"] + assert "pipeline_health" in change["example_after"] From 1cba05c43b3cabf1645df65e63ac4d234b132486 Mon Sep 17 00:00:00 2001 From: Trecek Date: Mon, 20 Jul 2026 09:43:14 -0700 Subject: [PATCH 08/10] fix(review): separate pipeline health action step names --- .../recipes/diagrams/implementation-groups.md | 2 +- .../recipes/diagrams/implementation.md | 2 +- src/autoskillit/recipes/diagrams/merge-prs.md | 2 +- .../recipes/diagrams/remediation.md | 2 +- .../recipes/implementation-groups.json | 32 ++++++------- .../recipes/implementation-groups.yaml | 33 +++++++------ src/autoskillit/recipes/implementation.json | 48 +++++++++---------- src/autoskillit/recipes/implementation.yaml | 48 +++++++++---------- src/autoskillit/recipes/merge-prs.json | 16 +++---- src/autoskillit/recipes/merge-prs.yaml | 16 +++---- src/autoskillit/recipes/remediation.json | 48 +++++++++---------- src/autoskillit/recipes/remediation.yaml | 48 +++++++++---------- tests/recipe/test_bundled_recipes_general.py | 14 +++--- .../test_check_ci_already_passed_routing.py | 16 +++---- tests/recipe/test_diagnostic_steps.py | 16 +++---- tests/recipe/test_implementation.py | 14 +++--- ..._implementation_groups_pr_decomposition.py | 6 +-- tests/recipe/test_remediation_recipe.py | 14 +++--- 18 files changed, 188 insertions(+), 189 deletions(-) diff --git a/src/autoskillit/recipes/diagrams/implementation-groups.md b/src/autoskillit/recipes/diagrams/implementation-groups.md index 2fca940c7..03c23d286 100644 --- a/src/autoskillit/recipes/diagrams/implementation-groups.md +++ b/src/autoskillit/recipes/diagrams/implementation-groups.md @@ -1,4 +1,4 @@ - + ## implementation-groups diff --git a/src/autoskillit/recipes/diagrams/implementation.md b/src/autoskillit/recipes/diagrams/implementation.md index ba2fa9fbe..afa48ae3e 100644 --- a/src/autoskillit/recipes/diagrams/implementation.md +++ b/src/autoskillit/recipes/diagrams/implementation.md @@ -1,4 +1,4 @@ - + ## implementation diff --git a/src/autoskillit/recipes/diagrams/merge-prs.md b/src/autoskillit/recipes/diagrams/merge-prs.md index e7b5ce42c..8815d135d 100644 --- a/src/autoskillit/recipes/diagrams/merge-prs.md +++ b/src/autoskillit/recipes/diagrams/merge-prs.md @@ -1,4 +1,4 @@ - + ## merge-prs Merge multiple PRs into an integration branch with conflict resolution and CI gates. diff --git a/src/autoskillit/recipes/diagrams/remediation.md b/src/autoskillit/recipes/diagrams/remediation.md index a9c5b4510..654c4b3cf 100644 --- a/src/autoskillit/recipes/diagrams/remediation.md +++ b/src/autoskillit/recipes/diagrams/remediation.md @@ -1,4 +1,4 @@ - + ## remediation diff --git a/src/autoskillit/recipes/implementation-groups.json b/src/autoskillit/recipes/implementation-groups.json index be46944cb..930036e77 100644 --- a/src/autoskillit/recipes/implementation-groups.json +++ b/src/autoskillit/recipes/implementation-groups.json @@ -1605,10 +1605,10 @@ "status": "error", "step_name": "register_clone_no_ci" }, - "on_success": "pipeline_health_no_ci", - "on_failure": "pipeline_health_no_ci" + "on_success": "analyze_pipeline_health_no_ci", + "on_failure": "analyze_pipeline_health_no_ci" }, - "pipeline_health_no_ci": { + "analyze_pipeline_health_no_ci": { "description": "Run post-pipeline diagnostic analysis on session logs (no-CI path)", "tool": "run_skill", "model": "", @@ -1618,7 +1618,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "escalate_stop_no_ci", "on_failure": "escalate_stop_no_ci", @@ -2518,11 +2518,11 @@ "status": "unconfirmed", "step_name": "register_clone_unconfirmed" }, - "on_success": "pipeline_health_unconfirmed", - "on_failure": "pipeline_health_unconfirmed", + "on_success": "analyze_pipeline_health_unconfirmed", + "on_failure": "analyze_pipeline_health_unconfirmed", "note": "Called when a merge-wait step times out before merge is confirmed. Does NOT call release_issue — the in-progress label stays on the issue so operators can see the PR is still actively queued. The clone is preserved (status: unconfirmed) for human inspection.\n" }, - "pipeline_health_unconfirmed": { + "analyze_pipeline_health_unconfirmed": { "description": "Run post-pipeline diagnostic analysis (unconfirmed path)", "tool": "run_skill", "model": "", @@ -2532,7 +2532,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "done_unconfirmed", "on_failure": "done_unconfirmed", @@ -2634,10 +2634,10 @@ "status": "success", "step_name": "register_clone_success" }, - "on_success": "pipeline_health", - "on_failure": "pipeline_health" + "on_success": "analyze_pipeline_health", + "on_failure": "analyze_pipeline_health" }, - "pipeline_health": { + "analyze_pipeline_health": { "description": "Run post-pipeline diagnostic analysis on session logs", "tool": "run_skill", "model": "", @@ -2647,7 +2647,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "done", "on_failure": "done", @@ -2663,10 +2663,10 @@ "status": "error", "step_name": "register_clone_failure" }, - "on_success": "pipeline_health_error", - "on_failure": "pipeline_health_error" + "on_success": "analyze_pipeline_health_error", + "on_failure": "analyze_pipeline_health_error" }, - "pipeline_health_error": { + "analyze_pipeline_health_error": { "description": "Run post-pipeline diagnostic analysis on session logs (error path)", "tool": "run_skill", "model": "", @@ -2676,7 +2676,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "escalate_stop", "on_failure": "escalate_stop", diff --git a/src/autoskillit/recipes/implementation-groups.yaml b/src/autoskillit/recipes/implementation-groups.yaml index 22e40aebc..9e34afbe4 100644 --- a/src/autoskillit/recipes/implementation-groups.yaml +++ b/src/autoskillit/recipes/implementation-groups.yaml @@ -1440,10 +1440,10 @@ steps: clone_path: "${{ context.work_dir }}" status: "error" step_name: register_clone_no_ci - on_success: pipeline_health_no_ci - on_failure: pipeline_health_no_ci + on_success: analyze_pipeline_health_no_ci + on_failure: analyze_pipeline_health_no_ci - pipeline_health_no_ci: + analyze_pipeline_health_no_ci: description: Run post-pipeline diagnostic analysis on session logs (no-CI path) tool: run_skill model: '' @@ -1454,7 +1454,7 @@ steps: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: escalate_stop_no_ci on_failure: escalate_stop_no_ci on_context_limit: escalate_stop_no_ci @@ -2252,15 +2252,15 @@ steps: clone_path: "${{ context.work_dir }}" status: "unconfirmed" step_name: register_clone_unconfirmed - on_success: pipeline_health_unconfirmed - on_failure: pipeline_health_unconfirmed + on_success: analyze_pipeline_health_unconfirmed + on_failure: analyze_pipeline_health_unconfirmed note: > Called when a merge-wait step times out before merge is confirmed. Does NOT call release_issue — the in-progress label stays on the issue so operators can see the PR is still actively queued. The clone is preserved (status: unconfirmed) for human inspection. - pipeline_health_unconfirmed: + analyze_pipeline_health_unconfirmed: description: Run post-pipeline diagnostic analysis (unconfirmed path) tool: run_skill model: '' @@ -2271,7 +2271,7 @@ steps: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: done_unconfirmed on_failure: done_unconfirmed on_context_limit: done_unconfirmed @@ -2390,10 +2390,10 @@ steps: clone_path: "${{ context.work_dir }}" status: "success" step_name: register_clone_success - on_success: pipeline_health - on_failure: pipeline_health + on_success: analyze_pipeline_health + on_failure: analyze_pipeline_health - pipeline_health: + analyze_pipeline_health: description: Run post-pipeline diagnostic analysis on session logs tool: run_skill model: '' @@ -2404,7 +2404,7 @@ steps: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: done on_failure: done on_context_limit: done @@ -2420,10 +2420,10 @@ steps: clone_path: "${{ context.work_dir }}" status: "error" step_name: register_clone_failure - on_success: pipeline_health_error - on_failure: pipeline_health_error + on_success: analyze_pipeline_health_error + on_failure: analyze_pipeline_health_error - pipeline_health_error: + analyze_pipeline_health_error: description: Run post-pipeline diagnostic analysis on session logs (error path) tool: run_skill model: '' @@ -2434,7 +2434,7 @@ steps: skill_command: /autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: escalate_stop on_failure: escalate_stop on_context_limit: escalate_stop @@ -2455,4 +2455,3 @@ steps: Pipeline failed — human intervention needed. Check the worktree and plan for details. Emit the L3 result sentinel JSON block now with success=false. Example sentinel: {"success": false, "reason": "implementation-groups pipeline failed"} - diff --git a/src/autoskillit/recipes/implementation.json b/src/autoskillit/recipes/implementation.json index 823f485a2..ec63b86ee 100644 --- a/src/autoskillit/recipes/implementation.json +++ b/src/autoskillit/recipes/implementation.json @@ -1677,10 +1677,10 @@ "status": "error", "step_name": "register_clone_no_ci" }, - "on_success": "pipeline_health_no_ci", - "on_failure": "pipeline_health_no_ci" + "on_success": "analyze_pipeline_health_no_ci", + "on_failure": "analyze_pipeline_health_no_ci" }, - "pipeline_health_no_ci": { + "analyze_pipeline_health_no_ci": { "description": "Run post-pipeline diagnostic analysis on session logs (no-CI path)", "tool": "run_skill", "model": "", @@ -1690,7 +1690,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "escalate_stop_no_ci", "on_failure": "escalate_stop_no_ci", @@ -2657,11 +2657,11 @@ "status": "unconfirmed", "step_name": "register_clone_unconfirmed" }, - "on_success": "pipeline_health_unconfirmed", - "on_failure": "pipeline_health_unconfirmed", + "on_success": "analyze_pipeline_health_unconfirmed", + "on_failure": "analyze_pipeline_health_unconfirmed", "note": "Called when a merge-wait step times out before merge is confirmed. Does NOT call release_issue — the in-progress label stays on the issue so operators can see the PR is still actively queued. The clone is preserved (status: unconfirmed) for human inspection.\n" }, - "pipeline_health_unconfirmed": { + "analyze_pipeline_health_unconfirmed": { "description": "Run post-pipeline diagnostic analysis on session logs (unconfirmed path)", "tool": "run_skill", "model": "", @@ -2671,7 +2671,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "done_unconfirmed", "on_failure": "done_unconfirmed", @@ -2703,8 +2703,8 @@ "status": "success", "step_name": "register_clone_success" }, - "on_success": "pipeline_health", - "on_failure": "pipeline_health" + "on_success": "analyze_pipeline_health", + "on_failure": "analyze_pipeline_health" }, "register_clone_failure": { "description": "Register clone as preserved (error pipeline)", @@ -2714,10 +2714,10 @@ "status": "error", "step_name": "register_clone_failure" }, - "on_success": "pipeline_health_error", - "on_failure": "pipeline_health_error" + "on_success": "analyze_pipeline_health_error", + "on_failure": "analyze_pipeline_health_error" }, - "pipeline_health": { + "analyze_pipeline_health": { "description": "Run post-pipeline diagnostic analysis on session logs", "tool": "run_skill", "model": "", @@ -2727,7 +2727,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "done", "on_failure": "done", @@ -2735,7 +2735,7 @@ "on_rate_limit": "done", "note": "Execute this diagnostic step. Failures are logged but do not alter pipeline routing. Both on_failure and on_context_limit route to the same terminal as on_success.\n" }, - "pipeline_health_error": { + "analyze_pipeline_health_error": { "description": "Run post-pipeline diagnostic analysis on session logs (error path)", "tool": "run_skill", "model": "", @@ -2745,7 +2745,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "escalate_stop", "on_failure": "escalate_stop", @@ -2761,10 +2761,10 @@ "status": "success", "step_name": "register_clone_no_changes" }, - "on_success": "pipeline_health_no_changes", - "on_failure": "pipeline_health_no_changes" + "on_success": "analyze_pipeline_health_no_changes", + "on_failure": "analyze_pipeline_health_no_changes" }, - "pipeline_health_no_changes": { + "analyze_pipeline_health_no_changes": { "description": "Run post-pipeline diagnostic analysis (zero-change path)", "tool": "run_skill", "model": "", @@ -2774,7 +2774,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "done_no_changes", "on_failure": "done_no_changes", @@ -2790,10 +2790,10 @@ "status": "success", "step_name": "register_clone_already_done" }, - "on_success": "pipeline_health_already_done", - "on_failure": "pipeline_health_already_done" + "on_success": "analyze_pipeline_health_already_done", + "on_failure": "analyze_pipeline_health_already_done" }, - "pipeline_health_already_done": { + "analyze_pipeline_health_already_done": { "description": "Run post-pipeline diagnostic analysis (already-done path)", "tool": "run_skill", "model": "", @@ -2803,7 +2803,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "done_already_done", "on_failure": "done_already_done", diff --git a/src/autoskillit/recipes/implementation.yaml b/src/autoskillit/recipes/implementation.yaml index 30285621b..7ff9854ad 100644 --- a/src/autoskillit/recipes/implementation.yaml +++ b/src/autoskillit/recipes/implementation.yaml @@ -1524,9 +1524,9 @@ steps: clone_path: ${{ context.work_dir }} status: error step_name: register_clone_no_ci - on_success: pipeline_health_no_ci - on_failure: pipeline_health_no_ci - pipeline_health_no_ci: + on_success: analyze_pipeline_health_no_ci + on_failure: analyze_pipeline_health_no_ci + analyze_pipeline_health_no_ci: description: Run post-pipeline diagnostic analysis on session logs (no-CI path) tool: run_skill model: '' @@ -1538,7 +1538,7 @@ steps: --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: escalate_stop_no_ci on_failure: escalate_stop_no_ci on_context_limit: escalate_stop_no_ci @@ -2420,15 +2420,15 @@ steps: clone_path: ${{ context.work_dir }} status: unconfirmed step_name: register_clone_unconfirmed - on_success: pipeline_health_unconfirmed - on_failure: pipeline_health_unconfirmed + on_success: analyze_pipeline_health_unconfirmed + on_failure: analyze_pipeline_health_unconfirmed note: 'Called when a merge-wait step times out before merge is confirmed. Does NOT call release_issue — the in-progress label stays on the issue so operators can see the PR is still actively queued. The clone is preserved (status: unconfirmed) for human inspection. ' - pipeline_health_unconfirmed: + analyze_pipeline_health_unconfirmed: description: Run post-pipeline diagnostic analysis on session logs (unconfirmed path) tool: run_skill @@ -2441,7 +2441,7 @@ steps: --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: done_unconfirmed on_failure: done_unconfirmed on_context_limit: done_unconfirmed @@ -2475,8 +2475,8 @@ steps: clone_path: ${{ context.work_dir }} status: success step_name: register_clone_success - on_success: pipeline_health - on_failure: pipeline_health + on_success: analyze_pipeline_health + on_failure: analyze_pipeline_health register_clone_failure: description: Register clone as preserved (error pipeline) tool: register_clone_status @@ -2484,9 +2484,9 @@ steps: clone_path: ${{ context.work_dir }} status: error step_name: register_clone_failure - on_success: pipeline_health_error - on_failure: pipeline_health_error - pipeline_health: + on_success: analyze_pipeline_health_error + on_failure: analyze_pipeline_health_error + analyze_pipeline_health: description: Run post-pipeline diagnostic analysis on session logs tool: run_skill model: '' @@ -2498,7 +2498,7 @@ steps: --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: done on_failure: done on_context_limit: done @@ -2507,7 +2507,7 @@ steps: routing. Both on_failure and on_context_limit route to the same terminal as on_success. ' - pipeline_health_error: + analyze_pipeline_health_error: description: Run post-pipeline diagnostic analysis on session logs (error path) tool: run_skill model: '' @@ -2519,7 +2519,7 @@ steps: --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: escalate_stop on_failure: escalate_stop on_context_limit: escalate_stop @@ -2535,9 +2535,9 @@ steps: clone_path: ${{ context.work_dir }} status: success step_name: register_clone_no_changes - on_success: pipeline_health_no_changes - on_failure: pipeline_health_no_changes - pipeline_health_no_changes: + on_success: analyze_pipeline_health_no_changes + on_failure: analyze_pipeline_health_no_changes + analyze_pipeline_health_no_changes: description: Run post-pipeline diagnostic analysis (zero-change path) tool: run_skill model: '' @@ -2549,7 +2549,7 @@ steps: --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: done_no_changes on_failure: done_no_changes on_context_limit: done_no_changes @@ -2565,9 +2565,9 @@ steps: clone_path: ${{ context.work_dir }} status: success step_name: register_clone_already_done - on_success: pipeline_health_already_done - on_failure: pipeline_health_already_done - pipeline_health_already_done: + on_success: analyze_pipeline_health_already_done + on_failure: analyze_pipeline_health_already_done + analyze_pipeline_health_already_done: description: Run post-pipeline diagnostic analysis (already-done path) tool: run_skill model: '' @@ -2579,7 +2579,7 @@ steps: --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: done_already_done on_failure: done_already_done on_context_limit: done_already_done diff --git a/src/autoskillit/recipes/merge-prs.json b/src/autoskillit/recipes/merge-prs.json index dc1f20c2a..8270aff65 100644 --- a/src/autoskillit/recipes/merge-prs.json +++ b/src/autoskillit/recipes/merge-prs.json @@ -1792,8 +1792,8 @@ "status": "success", "step_name": "register_clone_success" }, - "on_success": "pipeline_health", - "on_failure": "pipeline_health" + "on_success": "analyze_pipeline_health", + "on_failure": "analyze_pipeline_health" }, "register_clone_failure": { "description": "Register clone as preserved (error pipeline)", @@ -1803,10 +1803,10 @@ "status": "error", "step_name": "register_clone_failure" }, - "on_success": "pipeline_health_error", - "on_failure": "pipeline_health_error" + "on_success": "analyze_pipeline_health_error", + "on_failure": "analyze_pipeline_health_error" }, - "pipeline_health": { + "analyze_pipeline_health": { "description": "Run post-pipeline diagnostic analysis on session logs", "tool": "run_skill", "model": "", @@ -1816,7 +1816,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "done", "on_failure": "done", @@ -1824,7 +1824,7 @@ "on_rate_limit": "done", "note": "Execute this diagnostic step. Failures are logged but do not alter pipeline routing. Both on_failure and on_context_limit route to the same terminal as on_success.\n" }, - "pipeline_health_error": { + "analyze_pipeline_health_error": { "description": "Run post-pipeline diagnostic analysis on session logs (error path)", "tool": "run_skill", "model": "", @@ -1834,7 +1834,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "escalate_stop", "on_failure": "escalate_stop", diff --git a/src/autoskillit/recipes/merge-prs.yaml b/src/autoskillit/recipes/merge-prs.yaml index 376e7510a..5a26e35e8 100644 --- a/src/autoskillit/recipes/merge-prs.yaml +++ b/src/autoskillit/recipes/merge-prs.yaml @@ -1729,8 +1729,8 @@ steps: clone_path: ${{ context.work_dir }} status: success step_name: register_clone_success - on_success: pipeline_health - on_failure: pipeline_health + on_success: analyze_pipeline_health + on_failure: analyze_pipeline_health register_clone_failure: description: Register clone as preserved (error pipeline) tool: register_clone_status @@ -1738,9 +1738,9 @@ steps: clone_path: ${{ context.work_dir }} status: error step_name: register_clone_failure - on_success: pipeline_health_error - on_failure: pipeline_health_error - pipeline_health: + on_success: analyze_pipeline_health_error + on_failure: analyze_pipeline_health_error + analyze_pipeline_health: description: Run post-pipeline diagnostic analysis on session logs tool: run_skill model: '' @@ -1752,7 +1752,7 @@ steps: --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: done on_failure: done on_context_limit: done @@ -1761,7 +1761,7 @@ steps: routing. Both on_failure and on_context_limit route to the same terminal as on_success. ' - pipeline_health_error: + analyze_pipeline_health_error: description: Run post-pipeline diagnostic analysis on session logs (error path) tool: run_skill model: '' @@ -1773,7 +1773,7 @@ steps: --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: escalate_stop on_failure: escalate_stop on_context_limit: escalate_stop diff --git a/src/autoskillit/recipes/remediation.json b/src/autoskillit/recipes/remediation.json index dfc0fa4f7..f8a693ccb 100644 --- a/src/autoskillit/recipes/remediation.json +++ b/src/autoskillit/recipes/remediation.json @@ -1891,10 +1891,10 @@ "status": "error", "step_name": "register_clone_no_ci" }, - "on_success": "pipeline_health_no_ci", - "on_failure": "pipeline_health_no_ci" + "on_success": "analyze_pipeline_health_no_ci", + "on_failure": "analyze_pipeline_health_no_ci" }, - "pipeline_health_no_ci": { + "analyze_pipeline_health_no_ci": { "description": "Run post-pipeline diagnostic analysis on session logs (no-CI path)", "tool": "run_skill", "model": "", @@ -1904,7 +1904,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "escalate_stop_no_ci", "on_failure": "escalate_stop_no_ci", @@ -2843,11 +2843,11 @@ "status": "unconfirmed", "step_name": "register_clone_unconfirmed" }, - "on_success": "pipeline_health_unconfirmed", - "on_failure": "pipeline_health_unconfirmed", + "on_success": "analyze_pipeline_health_unconfirmed", + "on_failure": "analyze_pipeline_health_unconfirmed", "note": "Called when a merge-wait step times out before merge is confirmed. Does NOT call release_issue — the in-progress label stays on the issue so operators can see the PR is still actively queued. The clone is preserved (status: unconfirmed) for human inspection.\n" }, - "pipeline_health_unconfirmed": { + "analyze_pipeline_health_unconfirmed": { "description": "Run post-pipeline diagnostic analysis on session logs (unconfirmed path)", "tool": "run_skill", "model": "", @@ -2857,7 +2857,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "done_unconfirmed", "on_failure": "done_unconfirmed", @@ -2917,8 +2917,8 @@ "status": "success", "step_name": "register_clone_success" }, - "on_success": "pipeline_health", - "on_failure": "pipeline_health" + "on_success": "analyze_pipeline_health", + "on_failure": "analyze_pipeline_health" }, "register_clone_failure": { "description": "Register clone as preserved (error pipeline)", @@ -2928,10 +2928,10 @@ "status": "error", "step_name": "register_clone_failure" }, - "on_success": "pipeline_health_error", - "on_failure": "pipeline_health_error" + "on_success": "analyze_pipeline_health_error", + "on_failure": "analyze_pipeline_health_error" }, - "pipeline_health": { + "analyze_pipeline_health": { "description": "Run post-pipeline diagnostic analysis on session logs", "tool": "run_skill", "model": "", @@ -2941,7 +2941,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "done", "on_failure": "done", @@ -2949,7 +2949,7 @@ "on_rate_limit": "done", "note": "Execute this diagnostic step. Failures are logged but do not alter pipeline routing. Both on_failure and on_context_limit route to the same terminal as on_success.\n" }, - "pipeline_health_error": { + "analyze_pipeline_health_error": { "description": "Run post-pipeline diagnostic analysis on session logs (error path)", "tool": "run_skill", "model": "", @@ -2959,7 +2959,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "escalate_stop", "on_failure": "escalate_stop", @@ -2975,10 +2975,10 @@ "status": "success", "step_name": "register_clone_no_changes" }, - "on_success": "pipeline_health_no_changes", - "on_failure": "pipeline_health_no_changes" + "on_success": "analyze_pipeline_health_no_changes", + "on_failure": "analyze_pipeline_health_no_changes" }, - "pipeline_health_no_changes": { + "analyze_pipeline_health_no_changes": { "description": "Run post-pipeline diagnostic analysis (zero-change path)", "tool": "run_skill", "model": "", @@ -2988,7 +2988,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "done_no_changes", "on_failure": "done_no_changes", @@ -3004,10 +3004,10 @@ "status": "success", "step_name": "register_clone_already_done" }, - "on_success": "pipeline_health_already_done", - "on_failure": "pipeline_health_already_done" + "on_success": "analyze_pipeline_health_already_done", + "on_failure": "analyze_pipeline_health_already_done" }, - "pipeline_health_already_done": { + "analyze_pipeline_health_already_done": { "description": "Run post-pipeline diagnostic analysis (already-done path)", "tool": "run_skill", "model": "", @@ -3017,7 +3017,7 @@ "with": { "skill_command": "/autoskillit:analyze-pipeline-health ${{ inputs.kitchen_id }} --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }}", "cwd": "${{ context.work_dir }}", - "step_name": "pipeline_health" + "step_name": "analyze_pipeline_health" }, "on_success": "done_already_done", "on_failure": "done_already_done", diff --git a/src/autoskillit/recipes/remediation.yaml b/src/autoskillit/recipes/remediation.yaml index d82a343ec..3ebaba6dc 100644 --- a/src/autoskillit/recipes/remediation.yaml +++ b/src/autoskillit/recipes/remediation.yaml @@ -1719,9 +1719,9 @@ steps: clone_path: ${{ context.work_dir }} status: error step_name: register_clone_no_ci - on_success: pipeline_health_no_ci - on_failure: pipeline_health_no_ci - pipeline_health_no_ci: + on_success: analyze_pipeline_health_no_ci + on_failure: analyze_pipeline_health_no_ci + analyze_pipeline_health_no_ci: description: Run post-pipeline diagnostic analysis on session logs (no-CI path) tool: run_skill model: '' @@ -1733,7 +1733,7 @@ steps: --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: escalate_stop_no_ci on_failure: escalate_stop_no_ci on_context_limit: escalate_stop_no_ci @@ -2581,15 +2581,15 @@ steps: clone_path: ${{ context.work_dir }} status: unconfirmed step_name: register_clone_unconfirmed - on_success: pipeline_health_unconfirmed - on_failure: pipeline_health_unconfirmed + on_success: analyze_pipeline_health_unconfirmed + on_failure: analyze_pipeline_health_unconfirmed note: 'Called when a merge-wait step times out before merge is confirmed. Does NOT call release_issue — the in-progress label stays on the issue so operators can see the PR is still actively queued. The clone is preserved (status: unconfirmed) for human inspection. ' - pipeline_health_unconfirmed: + analyze_pipeline_health_unconfirmed: description: Run post-pipeline diagnostic analysis on session logs (unconfirmed path) tool: run_skill @@ -2602,7 +2602,7 @@ steps: --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: done_unconfirmed on_failure: done_unconfirmed on_context_limit: done_unconfirmed @@ -2668,8 +2668,8 @@ steps: clone_path: ${{ context.work_dir }} status: success step_name: register_clone_success - on_success: pipeline_health - on_failure: pipeline_health + on_success: analyze_pipeline_health + on_failure: analyze_pipeline_health register_clone_failure: description: Register clone as preserved (error pipeline) tool: register_clone_status @@ -2677,9 +2677,9 @@ steps: clone_path: ${{ context.work_dir }} status: error step_name: register_clone_failure - on_success: pipeline_health_error - on_failure: pipeline_health_error - pipeline_health: + on_success: analyze_pipeline_health_error + on_failure: analyze_pipeline_health_error + analyze_pipeline_health: description: Run post-pipeline diagnostic analysis on session logs tool: run_skill model: '' @@ -2691,7 +2691,7 @@ steps: --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: done on_failure: done on_context_limit: done @@ -2700,7 +2700,7 @@ steps: routing. Both on_failure and on_context_limit route to the same terminal as on_success. ' - pipeline_health_error: + analyze_pipeline_health_error: description: Run post-pipeline diagnostic analysis on session logs (error path) tool: run_skill model: '' @@ -2712,7 +2712,7 @@ steps: --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: escalate_stop on_failure: escalate_stop on_context_limit: escalate_stop @@ -2728,9 +2728,9 @@ steps: clone_path: ${{ context.work_dir }} status: success step_name: register_clone_no_changes - on_success: pipeline_health_no_changes - on_failure: pipeline_health_no_changes - pipeline_health_no_changes: + on_success: analyze_pipeline_health_no_changes + on_failure: analyze_pipeline_health_no_changes + analyze_pipeline_health_no_changes: description: Run post-pipeline diagnostic analysis (zero-change path) tool: run_skill model: '' @@ -2742,7 +2742,7 @@ steps: --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: done_no_changes on_failure: done_no_changes on_context_limit: done_no_changes @@ -2758,9 +2758,9 @@ steps: clone_path: ${{ context.work_dir }} status: success step_name: register_clone_already_done - on_success: pipeline_health_already_done - on_failure: pipeline_health_already_done - pipeline_health_already_done: + on_success: analyze_pipeline_health_already_done + on_failure: analyze_pipeline_health_already_done + analyze_pipeline_health_already_done: description: Run post-pipeline diagnostic analysis (already-done path) tool: run_skill model: '' @@ -2772,7 +2772,7 @@ steps: --dispatch-id=${{ inputs.dispatch_id }} --diagnostics-log-dir=${{ inputs.diagnostics_log_dir }} cwd: ${{ context.work_dir }} - step_name: pipeline_health + step_name: analyze_pipeline_health on_success: done_already_done on_failure: done_already_done on_context_limit: done_already_done diff --git a/tests/recipe/test_bundled_recipes_general.py b/tests/recipe/test_bundled_recipes_general.py index 880d872c9..2ae4ab05c 100644 --- a/tests/recipe/test_bundled_recipes_general.py +++ b/tests/recipe/test_bundled_recipes_general.py @@ -684,18 +684,18 @@ def test_recipe_has_unconditional_register_steps(recipe_name: str) -> None: assert "register_clone_failure" in recipe.steps s = recipe.steps["register_clone_success"] f = recipe.steps["register_clone_failure"] - # Accept direct routing to done/escalate_stop OR indirect via optional pipeline_health steps - assert s.on_success in ("done", "pipeline_health"), ( - "register_clone_success.on_success must route to done or pipeline_health, " + # Accept direct routing or indirect routing through optional pipeline-health analysis + assert s.on_success in ("done", "analyze_pipeline_health"), ( + "register_clone_success.on_success must route to done or analyze_pipeline_health, " f"got {s.on_success!r}" ) - assert f.on_success in ("escalate_stop", "pipeline_health_error"), ( + assert f.on_success in ("escalate_stop", "analyze_pipeline_health_error"), ( "register_clone_failure.on_success must route to escalate_stop or " - f"pipeline_health_error, got {f.on_success!r}" + f"analyze_pipeline_health_error, got {f.on_success!r}" ) - assert f.on_failure in ("escalate_stop", "pipeline_health_error"), ( + assert f.on_failure in ("escalate_stop", "analyze_pipeline_health_error"), ( "register_clone_failure.on_failure must route to escalate_stop or " - f"pipeline_health_error, got {f.on_failure!r}" + f"analyze_pipeline_health_error, got {f.on_failure!r}" ) assert "check_defer_cleanup" not in recipe.steps assert "check_defer_on_failure" not in recipe.steps diff --git a/tests/recipe/test_check_ci_already_passed_routing.py b/tests/recipe/test_check_ci_already_passed_routing.py index f0682de42..5e145b129 100644 --- a/tests/recipe/test_check_ci_already_passed_routing.py +++ b/tests/recipe/test_check_ci_already_passed_routing.py @@ -90,7 +90,7 @@ def test_no_direct_escalate_stop_no_ci_callers_except_safety_net(recipe): "escalate_stop_no_ci", "mark_issue_failed_no_ci", "register_clone_no_ci", - "pipeline_health_no_ci", + "analyze_pipeline_health_no_ci", } for name, step in recipe.steps.items(): if name in EXCLUDED: @@ -116,14 +116,14 @@ def test_register_clone_no_ci_routes_to_escalate_stop_no_ci(recipe): """register_clone_no_ci registers clone as error and routes toward escalate_stop_no_ci.""" step = recipe.steps["register_clone_no_ci"] assert step.tool == "register_clone_status" - # May route via optional pipeline_health_no_ci step first - assert step.on_success in ("escalate_stop_no_ci", "pipeline_health_no_ci"), ( + # May route via optional analyze_pipeline_health_no_ci step first + assert step.on_success in ("escalate_stop_no_ci", "analyze_pipeline_health_no_ci"), ( "register_clone_no_ci.on_success must route to escalate_stop_no_ci " - f"or pipeline_health_no_ci, got {step.on_success!r}" + f"or analyze_pipeline_health_no_ci, got {step.on_success!r}" ) - assert step.on_failure in ("escalate_stop_no_ci", "pipeline_health_no_ci"), ( + assert step.on_failure in ("escalate_stop_no_ci", "analyze_pipeline_health_no_ci"), ( "register_clone_no_ci.on_failure must route to escalate_stop_no_ci " - f"or pipeline_health_no_ci, got {step.on_failure!r}" + f"or analyze_pipeline_health_no_ci, got {step.on_failure!r}" ) assert step.with_args.get("status") == "error" @@ -139,8 +139,8 @@ def test_no_ci_failure_chain_complete(recipe): assert mark_step.on_success == "register_clone_no_ci" reg_step = recipe.steps["register_clone_no_ci"] - # May route via optional pipeline_health_no_ci step that then routes to escalate_stop_no_ci - assert reg_step.on_success in ("escalate_stop_no_ci", "pipeline_health_no_ci"), ( + # The optional analysis step may route onward to escalate_stop_no_ci. + assert reg_step.on_success in ("escalate_stop_no_ci", "analyze_pipeline_health_no_ci"), ( "register_clone_no_ci.on_success must route toward escalate_stop_no_ci, " f"got {reg_step.on_success!r}" ) diff --git a/tests/recipe/test_diagnostic_steps.py b/tests/recipe/test_diagnostic_steps.py index 3b1af1f85..ef8ed52b1 100644 --- a/tests/recipe/test_diagnostic_steps.py +++ b/tests/recipe/test_diagnostic_steps.py @@ -39,13 +39,13 @@ def test_analyze_pipeline_health_coordinator_validates_scanners(): ) -# DIAG_C9: pipeline_health steps have required fields in implementation recipe +# DIAG_C9: analyze_pipeline_health steps have required fields in implementation recipe @pytest.mark.parametrize("recipe_name", ["implementation", "remediation", "merge-prs"]) -def test_pipeline_health_steps_have_required_fields(recipe_name): - """pipeline_health steps must have on_context_limit, optional=true, skip_when_false.""" +def test_analyze_pipeline_health_steps_have_required_fields(recipe_name): + """analyze_pipeline_health steps must have required optional-step fields.""" recipe = load_recipe(builtin_recipes_dir() / f"{recipe_name}.yaml") for name, step in recipe.steps.items(): - if name.startswith("pipeline_health"): + if name.startswith("analyze_pipeline_health"): assert step.on_context_limit is not None, f"{name} missing on_context_limit" assert step.optional is True, f"{name} optional must be True" assert step.skip_when_false == "inputs.pipeline_health", ( @@ -56,7 +56,7 @@ def test_pipeline_health_steps_have_required_fields(recipe_name): # T7: REQ-TEST-004 def test_implementation_family_recipes_route_terminals_through_diagnostics() -> None: """REQ-TEST-004: Every register_clone_* terminal in implementation-family recipes - routes through a pipeline_health* step gated on pipeline_health.""" + routes through an analyze_pipeline_health* step gated on pipeline_health.""" recipes_dir = builtin_recipes_dir() target_names = ["implementation.yaml", "implementation-groups.yaml"] missing: list[str] = [] @@ -66,7 +66,7 @@ def test_implementation_family_recipes_route_terminals_through_diagnostics() -> missing.append(name) assert not missing, f"Recipe files not found: {missing}" - diag_step_prefixes = ("pipeline_health",) + diag_step_prefixes = ("analyze_pipeline_health",) required_post_run_refs = ("inputs.pipeline_health",) for name in target_names: @@ -76,14 +76,14 @@ def test_implementation_family_recipes_route_terminals_through_diagnostics() -> clone_steps = [(n, s) for n, s in steps.items() if n.startswith("register_clone_")] assert clone_steps, f"{name}: expected at least one register_clone_* step" for step_name, cs in clone_steps: - # The step must route on_success to a pipeline_health* step + # The step must route on_success to an analyze_pipeline_health* step next_step = cs.on_success assert next_step is not None, f"{name}: {step_name} has no on_success" assert next_step.startswith(diag_step_prefixes), ( f"{name}: {step_name}.on_success={next_step!r} must start with " f"{diag_step_prefixes!r}" ) - # The pipeline_health* step must gate on inputs.pipeline_health + # The analyze_pipeline_health* step must gate on inputs.pipeline_health diag = steps.get(next_step) assert diag is not None, ( f"{name}: step {step_name} routes to {next_step!r} but no such step exists" diff --git a/tests/recipe/test_implementation.py b/tests/recipe/test_implementation.py index 8b4855343..74f2f4c2b 100644 --- a/tests/recipe/test_implementation.py +++ b/tests/recipe/test_implementation.py @@ -244,28 +244,28 @@ def test_done_already_done_stop_exists(recipe) -> None: def test_register_clone_no_changes_routes_to_diagnostic(recipe) -> None: - """register_clone_no_changes must route to pipeline_health_no_changes.""" + """register_clone_no_changes must route to analyze_pipeline_health_no_changes.""" assert "register_clone_no_changes" in recipe.steps step = recipe.steps["register_clone_no_changes"] - assert step.on_success == "pipeline_health_no_changes" + assert step.on_success == "analyze_pipeline_health_no_changes" def test_register_clone_already_done_routes_to_diagnostic(recipe) -> None: - """register_clone_already_done must route to pipeline_health_already_done.""" + """register_clone_already_done must route to analyze_pipeline_health_already_done.""" assert "register_clone_already_done" in recipe.steps step = recipe.steps["register_clone_already_done"] - assert step.on_success == "pipeline_health_already_done" + assert step.on_success == "analyze_pipeline_health_already_done" def test_register_clone_unconfirmed_routes_to_done_unconfirmed(recipe) -> None: """register_clone_unconfirmed must route toward done_unconfirmed.""" step = recipe.steps["register_clone_unconfirmed"] - # May route via optional pipeline_health_unconfirmed step first - assert step.on_success in ("done_unconfirmed", "pipeline_health_unconfirmed"), ( + # May route via optional analyze_pipeline_health_unconfirmed step first + assert step.on_success in ("done_unconfirmed", "analyze_pipeline_health_unconfirmed"), ( "register_clone_unconfirmed.on_success must route toward done_unconfirmed, " f"got {step.on_success!r}" ) - assert step.on_failure in ("done_unconfirmed", "pipeline_health_unconfirmed"), ( + assert step.on_failure in ("done_unconfirmed", "analyze_pipeline_health_unconfirmed"), ( "register_clone_unconfirmed.on_failure must route toward done_unconfirmed, " f"got {step.on_failure!r}" ) diff --git a/tests/recipe/test_implementation_groups_pr_decomposition.py b/tests/recipe/test_implementation_groups_pr_decomposition.py index 6f793e753..420cf596a 100644 --- a/tests/recipe/test_implementation_groups_pr_decomposition.py +++ b/tests/recipe/test_implementation_groups_pr_decomposition.py @@ -68,7 +68,7 @@ def test_done_unconfirmed_stop_exists(recipe) -> None: def test_register_clone_unconfirmed_routes_to_done_unconfirmed(recipe) -> None: - """register_clone_unconfirmed must route to pipeline_health_unconfirmed.""" + """register_clone_unconfirmed must route to analyze_pipeline_health_unconfirmed.""" step = recipe.steps["register_clone_unconfirmed"] - assert step.on_success == "pipeline_health_unconfirmed" - assert step.on_failure == "pipeline_health_unconfirmed" + assert step.on_success == "analyze_pipeline_health_unconfirmed" + assert step.on_failure == "analyze_pipeline_health_unconfirmed" diff --git a/tests/recipe/test_remediation_recipe.py b/tests/recipe/test_remediation_recipe.py index 9aaacf0b9..e4bab32e5 100644 --- a/tests/recipe/test_remediation_recipe.py +++ b/tests/recipe/test_remediation_recipe.py @@ -251,28 +251,28 @@ def test_done_already_done_stop_exists(recipe) -> None: def test_register_clone_no_changes_routes_to_diagnostic(recipe) -> None: - """register_clone_no_changes must route to pipeline_health_no_changes.""" + """register_clone_no_changes must route to analyze_pipeline_health_no_changes.""" assert "register_clone_no_changes" in recipe.steps step = recipe.steps["register_clone_no_changes"] - assert step.on_success == "pipeline_health_no_changes" + assert step.on_success == "analyze_pipeline_health_no_changes" def test_register_clone_already_done_routes_to_diagnostic(recipe) -> None: - """register_clone_already_done must route to pipeline_health_already_done.""" + """register_clone_already_done must route to analyze_pipeline_health_already_done.""" assert "register_clone_already_done" in recipe.steps step = recipe.steps["register_clone_already_done"] - assert step.on_success == "pipeline_health_already_done" + assert step.on_success == "analyze_pipeline_health_already_done" def test_register_clone_unconfirmed_routes_to_done_unconfirmed(recipe) -> None: """register_clone_unconfirmed must route toward done_unconfirmed.""" step = recipe.steps["register_clone_unconfirmed"] - # May route via optional pipeline_health_unconfirmed step first - assert step.on_success in ("done_unconfirmed", "pipeline_health_unconfirmed"), ( + # May route via optional analyze_pipeline_health_unconfirmed step first + assert step.on_success in ("done_unconfirmed", "analyze_pipeline_health_unconfirmed"), ( "register_clone_unconfirmed.on_success must route toward done_unconfirmed, " f"got {step.on_success!r}" ) - assert step.on_failure in ("done_unconfirmed", "pipeline_health_unconfirmed"), ( + assert step.on_failure in ("done_unconfirmed", "analyze_pipeline_health_unconfirmed"), ( "register_clone_unconfirmed.on_failure must route toward done_unconfirmed, " f"got {step.on_failure!r}" ) From 704d1e4649d37530236cfdf2c01801b71436760e Mon Sep 17 00:00:00 2001 From: Trecek Date: Mon, 20 Jul 2026 09:43:41 -0700 Subject: [PATCH 09/10] fix(review): prevent vacuous pipeline health step checks --- tests/recipe/test_diagnostic_steps.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/recipe/test_diagnostic_steps.py b/tests/recipe/test_diagnostic_steps.py index ef8ed52b1..dc39d6f48 100644 --- a/tests/recipe/test_diagnostic_steps.py +++ b/tests/recipe/test_diagnostic_steps.py @@ -44,13 +44,18 @@ def test_analyze_pipeline_health_coordinator_validates_scanners(): def test_analyze_pipeline_health_steps_have_required_fields(recipe_name): """analyze_pipeline_health steps must have required optional-step fields.""" recipe = load_recipe(builtin_recipes_dir() / f"{recipe_name}.yaml") - for name, step in recipe.steps.items(): - if name.startswith("analyze_pipeline_health"): - assert step.on_context_limit is not None, f"{name} missing on_context_limit" - assert step.optional is True, f"{name} optional must be True" - assert step.skip_when_false == "inputs.pipeline_health", ( - f"{name} skip_when_false must be inputs.pipeline_health" - ) + analysis_steps = [ + (name, step) + for name, step in recipe.steps.items() + if name.startswith("analyze_pipeline_health") + ] + assert analysis_steps, f"{recipe_name}: expected at least one analyze_pipeline_health step" + for name, step in analysis_steps: + assert step.on_context_limit is not None, f"{name} missing on_context_limit" + assert step.optional is True, f"{name} optional must be True" + assert step.skip_when_false == "inputs.pipeline_health", ( + f"{name} skip_when_false must be inputs.pipeline_health" + ) # T7: REQ-TEST-004 From 34f5e8fb188b2b0dc7e20f053f08856186904a7d Mon Sep 17 00:00:00 2001 From: Trecek Date: Mon, 20 Jul 2026 09:47:43 -0700 Subject: [PATCH 10/10] fix(review): refresh recipe response size ceilings --- tests/infra/test_pretty_output_recipe.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/infra/test_pretty_output_recipe.py b/tests/infra/test_pretty_output_recipe.py index ac70098d8..b544178ec 100644 --- a/tests/infra/test_pretty_output_recipe.py +++ b/tests/infra/test_pretty_output_recipe.py @@ -1052,8 +1052,8 @@ def test_canonical_recipe_responses_fit_independent_registry_ceilings(tmp_path, for ingredients_only in (False, True) } assert maxima == { - "load_recipe": (182_796, "remediation", "all_truthy"), - "open_kitchen": (182_855, "remediation", "all_truthy"), + "load_recipe": (183_420, "remediation", "all_truthy"), + "open_kitchen": (183_479, "remediation", "all_truthy"), }