Skip to content

Rectify: audit_impl preflight rejects the plan path the recipe supplies (#4387) - #4403

Merged
Trecek merged 6 commits into
developfrom
audit-impl-preflight-rejects-the-plan-path-the-recipe-suppli/4387
Jul 28, 2026
Merged

Rectify: audit_impl preflight rejects the plan path the recipe supplies (#4387)#4403
Trecek merged 6 commits into
developfrom
audit-impl-preflight-rejects-the-plan-path-the-recipe-suppli/4387

Conversation

@Trecek

@Trecek Trecek commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

The audit-cycle containment chain — preflight resolver, loaded-publish, verified-publish, reported-publish — hardcodes tool_ctx.temp_dir (the orchestrator's .autoskillit/temp/) as allowed_root. In clone-based pipelines, artifacts live under the clone's .autoskillit/temp/, a structurally disjoint path. The containment check always fails, producing a ContainmentError that routes to register_clone_failureescalate_stop, indistinguishably from a genuine NO GO verdict. This plan addresses all three acceptance criteria from #4387:

  1. Fix the containment root mismatch so audit_impl can reach a verdict in clone-based pipelines.
  2. Distinguish preflight/infrastructure failure from a genuine NO GO in routing and result envelope.
  3. Regression tests that structurally prevent the test-gap pattern (co-located roots) from masking this class of bug.

Requirements

  • audit_impl completes and returns a verdict on a standard clone-based remediation run
    with open_pr=true.
  • A preflight failure is distinguishable from a NO GO in routing and in the result envelope.
  • A test constructs the clone-based layout (work_dir outside the orchestrator temp) and
    asserts the preflight admits the recipe-supplied plan path.

Closes #4387

Implementation Plan

Plan file: /home/talon/projects/autoskillit-runs/fix-4387-20260727-213059-759256/.autoskillit/temp/rectify/rectify_audit_impl_preflight_containment_root_2026-07-27_214500.md

🤖 Generated with Claude Code via AutoSkillit

Trecek added 6 commits July 28, 2026 07:48
The audit-cycle containment chain (preflight resolver, loaded-publish,
verified-publish, reported-publish) hardcoded tool_ctx.temp_dir as
allowed_root. In clone-based pipelines, artifacts live under the
clone's .autoskillit/temp/, a structurally disjoint path. The
containment check always failed, producing a ContainmentError that
routed to register_clone_failure -> escalate_stop, indistinguishably
from a genuine NO GO verdict.

Changes:
- Add allowed_root kwarg override to InputPreflightResolver.resolve()
- DefaultInputPreflightResolver creates a fresh AuditCycleVerifier when
  allowed_root is provided
- resolve_attested_input_preflight threads allowed_root to the resolver
- run_skill computes _clone_allowed_root = resolve_temp_dir(Path(cwd),
  tool_ctx.config.workspace.temp_dir) before the if/elif chain and
  passes it to both preflight and publish call sites
- _publish_loaded_audit_cycle, publish_verified_audit_cycle,
  publish_reported_audit_cycle, publish_audit_cycle_result now take
  required allowed_root: Path parameter (replacing tool_ctx.temp_dir
  reads)
- implementation.yaml: route preflight:stage condition to
  register_clone_failure (preserves clone for diagnosis) and
  result.error to check_audit_remediation_loop (was register_clone_failure)
- Test call sites updated to pass allowed_root to publish functions
- RecordingResolver and RejectingResolver test doubles updated to
  accept allowed_root kwarg
- Three new regression tests:
  * test_clone_layout_containment_root_required — disjoint
    orchestrator_root vs clone_temp directly reproduces #4387
  * test_recipe_execution_deny_envelope_carries_preflight_stage —
    locks down the deny envelope shape
  * test_preflight_resolver_protocol_accepts_allowed_root_override —
    exercises allowed_root kwarg override and fallback semantics
…iagram hash; update NO GO test filter for preflight routing
Empty cwd previously fell through the truthy-guarded boundary checks and
anchored the audit-cycle containment root to the MCP server process's own
cwd instead of failing closed. Scoped to the recipe-execution-active path
(the only place the containment anchor is actually consumed) so ad-hoc
skill invocations with no directory requirement remain unaffected.
…ot wiring

The two existing #4387 regression tests exercise DefaultInputPreflightResolver
directly and never call run_skill(), so the actual wiring bug (orchestrator
temp_dir disjoint from the clone temp tree) was never reproduced through the
real MCP entry point. Adds a run_skill()-level test with genuinely disjoint
orchestrator/clone directory trees, verified to fail without the
_clone_allowed_root fix and pass with it.
…ill regression test

The newly added run_skill()-level regression test for #4387
(test_run_skill_containment_root_anchors_to_cwd_not_orchestrator_temp_dir)
was written without the supporting lifecycle hooks used by every other
working run_skill regression test in the same file:

1. install_recipe_execution(snapshot=...) requires a staged initialization;
   the test was calling it directly and raising
   RecipeExecutionAdmissionError('recipe execution cannot install before
   initialization is staged').

2. preflight_identities were written to tool_ctx.active_recipe_execution,
   but run_skill reads the installed execution from
   recipe_initialization_state via get_recipe_execution(), so the preflight
   gate raised recipe_execution_preflight_identity_missing.

3. The trusted-head publish was issued BEFORE
   _replace_test_recipe_execution. install_recipe_execution clears the
   previous generation's heads via clear_generation() when previous is not
   installed (true for any dataclasses.replace()-derived prepared
   execution), so the publish was wiped before the resolver could read it,
   raising input_preflight_head_missing.

Switch to the existing _install_test_recipe_execution helper (which stages
initialization before installing) and _replace_test_recipe_execution (which
threads preflight_identities into recipe_initialization_state). Reorder so
the publish happens after the replace.
@Trecek
Trecek force-pushed the audit-impl-preflight-rejects-the-plan-path-the-recipe-suppli/4387 branch from c78bcf4 to 2a3456c Compare July 28, 2026 15:08

@Trecek Trecek left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

AutoSkillit review passed. No blocking issues found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant