Repository navigation
fix(tests): restore canonical fixture contracts for CI - #3338
Conversation
Repair the 39 bounded fixture/oracle cases in #3335 and two neighboring managed-MCP file-level controls without changing production behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: cab562e7-8146-4ec0-b3b6-3af23efc7247
Docs sync advisoryVerdict: no_change * Pages affected: 0 * LLM calls: 1/15 * Took: 1.13s (deterministic recovery) No additional documentation changes are needed. All 23 changed paths match The requested classifier agent could not access filesystem/shell tools and returned blocked. The orchestrator recovered the deterministic L0 path check directly against the live PR diff and This advisory does not review prose quality or qualify CI/merge readiness. Confidence: high; source: L0; CDO redrafts: 0. Generated by docs-sync. This comment is AI-generated and may contain errors. |
There was a problem hiding this comment.
🟡 Changes recommended
Two new LF-only byte assertions conflict with Windows fixture newline translation and fail despite correct preservation behavior.
2 open issues
What changed in this PR
Repairs the bounded test-fixture and assertion drift tracked in #3335 without changing production code. The changes align integration tests with current source-admission, managed-ownership, and lifecycle contracts.
Changes:
- Replace incomplete downloader mocks and hand-authored cleanup authority with real models, materialized sources, and writer-generated evidence.
- Update preservation, policy, diagnostic, frozen-replay, and identity assertions while retaining negative controls.
- Document source and ownership fixture requirements.
| File | Description |
|---|---|
| tests/utils/materialized_downloader.py | Adds package-specific source materialization. |
| tests/utils/managed_mcp.py | Generates real managed MCP write evidence. |
| tests/integration/test_wave6_integrators_coverage.py | Uses authorized Claude cleanup fixtures. |
| tests/integration/test_update_mcp_lsp_prune.py | Supplies real sources and update references. |
| tests/integration/test_skill_integrator_hermetic.py | Exercises console fallback and promoted bytes. |
| tests/integration/test_selective_install_mcp.py | Materializes dependency graphs and rejects invalid sources. |
| tests/integration/test_policy_install_e2e.py | Requires successful warn-mode installation. |
| tests/integration/test_mcp_integrator_install_flow.py | Verifies cleanup with managed ownership evidence. |
| tests/integration/test_mcp_integrator_characterisation.py | Covers real clients, cleanup refusal, and survivors. |
| tests/integration/test_integrators_validation_rules.py | Updates canonical local-source diagnostics. |
| tests/integration/test_integrators_end_to_end.py | Checks authorized cleanup and unverifiable-entry preservation. |
| tests/integration/test_hermetic_lifecycle_foundation.py | Requires exact identity-tamper findings. |
| tests/integration/test_grok_audit_target_lifecycle.py | Checks preservation before explicit repair. |
| tests/integration/test_govern_core_contract.py | Distinguishes policy provenance while preserving semantic equality. |
| tests/integration/test_global_mcp_lockfile_e2e.py | Materializes sources for global lockfile tests. |
| tests/integration/test_github_downloader_validation_flow.py | Exercises virtual download materialization. |
| tests/integration/test_github_downloader_phase3w4.py | Verifies persisted virtual-file metadata and bytes. |
| tests/integration/test_frozen_native_service_lifecycle.py | Uses controlled generic Git with preflight tracing. |
| tests/integration/test_frozen_cold_cache_apm_package_e2e.py | Builds genuine baselines and checks frozen mismatch refusal. |
| tests/integration/test_deps_models_validation.py | Tests empty projects and explicit lockfile creation. |
| tests/integration/test_commands_mcp_flow.py | Updates diagnostics and valid-manifest acceptance. |
| tests/integration/test_codex_windows_toml_install.py | Adds ownership-backed cleanup and refusal controls. |
| docs/src/content/docs/contributing/integration-testing.md | Documents source and ownership fixture contracts. |
Review effort: Balanced
Address review4342274477 and4342274556 with explicit LF/CRLF tamper bytes and source-byte promotion oracles; retain protection, repair, count, path, and console checks. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: cab562e7-8146-4ec0-b3b6-3af23efc7247
Merge Master assessment: ship_nowAt Both Copilot findings were legitimate and are fixed: tampering now writes explicit LF/CRLF bytes across all four original target variants; promotion compares a pre-copy source-byte snapshot across native/LF/CRLF inputs. Exact preservation, receipts, failing audit before explicit force, repair, count, path and console assertions remain. Both original threads are resolved.
I independently checked all 49 recovery and 43 original artifact digests, all 23 published source-file hashes, runtime binding, JUnit outcomes, review resolution and actual-main compatibility. Canonical completion validation and strict terminal owner-v2 verification pass with zero production-owner touches; functional proof is recorded separately, not fabricated as owner rows. Current The original independent review missed these newline defects. A same-persona, recovered-context review of the two-file delta found no remaining issues; this is not a full-panel/CEO verdict or a claimed hosted-Windows reproduction. This is my separate merge-readiness assessment, not a rewritten source/reviewer verdict. Only #3335 is completed by this PR. The original Generated by autopilot-pr-merge-worker. This comment is AI-generated and may contain errors. |

fix(tests): restore canonical fixture contracts for CI
Description
TL;DR
Repair the 39 bounded fixture/oracle cases in #3335 without changing production code.
Downloader fixtures materialize valid per-package trees, MCP cleanup fixtures obtain real managed-write evidence, and assertions follow current preservation, policy, diagnostic and identity contracts.
The recovery at
125d7c4bafixes two review-identified Windows newline assumptions with exact LF/CRLF byte controls; historical full affected-file proof remains bound to6ec1665bf.Important
This is the sole corrective carrier for #3335, not a claim that all CI is green.
The named-package case qualifies controlled generic Git, not GitHub REST.
Only the designated merge manager qualifies or merges this PR; new-head hosted checks are tracked separately.
Problem (WHY)
3b9a8503produced 37 failures and one pass; invalid mock paths and unverified native cleanup prevented meaningful behavioral assertions.6ec1665bffound two real newline assumptions: translated tamper writes and an LF-only expectation for copied source bytes. These are static causal findings, not reproduced hosted Windows failures.The repair uses execution evidence instead of accepting mock-error exits as success, following Agent Skills' guidance: "Read agent execution traces, not just final outputs."
Approach (WHAT)
PackageInfo/ResolvedReferencemodels and physical sources at the requested install path, including staging.--forcerepair; retain unforced clean/missing-file behavior.Implementation (HOW)
Paths below are relative to
tests/integration/, except explicitly qualified helper/documentation paths.tests/utils/materialized_downloader.pytest_selective_install_mcp.pytest_global_mcp_lockfile_e2e.pytest_update_mcp_lsp_prune.pytest_policy_install_e2e.pytests/utils/managed_mcp.pytest_codex_windows_toml_install.pytest_integrators_end_to_end.pytest_mcp_integrator_characterisation.pytest_mcp_integrator_install_flow.py,test_wave6_integrators_coverage.pytest_commands_mcp_flow.py,test_integrators_validation_rules.pytest_grok_audit_target_lifecycle.pytest_govern_core_contract.pyfile:versus warmorg:source, enforcement state/mode and complete remaining semantic equality.test_github_downloader_phase3w4.py,test_github_downloader_validation_flow.pytest_deps_models_validation.pytest_frozen_cold_cache_apm_package_e2e.pydependencies.mcp, genuine initial install, cold replay and declaration-mismatch rejection.test_frozen_native_service_lifecycle.pyls-remote, original commits and native/frozen controls.test_skill_integrator_hermetic.pytest_hermetic_lifecycle_foundation.pydocs/src/content/docs/contributing/integration-testing.mdRecovery details: explicit tamper bytes, source-byte promotion oracle.
Diagram
Dashed nodes are new fixture helpers; production admission and ownership decisions remain unchanged.
flowchart LR subgraph Fixtures["Corrected test inputs"] S["stub_materialized_downloader"] M["install_managed_mcp"] end subgraph Authority["Unchanged canonical owners"] D["Source admission"] W["MCPIntegrator._install_for_runtime"] R["MCPIntegrator.remove_stale"] end subgraph Oracles["Load-bearing assertions"] G["Transitive graph and exact lock"] P["Foreign or unverifiable bytes preserved"] C["Authorized stale entry removed"] end S -->|"PackageInfo and physical staging tree"| D D --> G M --> W W -->|"Declaration and actual native receipt"| R R --> P R --> C classDef new stroke-dasharray: 5 5; class S,M new;Trade-offs
apm installrecords a stale dependencyversioninapm.lock.yamlwhenapm_modules/holds the previous version #3246, I5, production, security, workflows and releases remain outside this correction. No CHANGELOG entry for test/guidance-only changes.Benefits
Issue and approved scope
Issue: Fixes #3335.
Human scope-approval comment: existing direct maintainer CI execution direction, recorded in #3335 under Execution authority and ownership: "I do not agree that you park the fix to CI, move full steam ahead, being idle and waiting for me to agree is not acceptable. Your mission is to fix CI". This is not a new approval record or accepted label. Review contact: Daniel Meppiel (@danielmeppiel).
Bounded scope is original 38 plus the explicitly added identity case. Two neighboring MCP characterisation fixtures were corrected under the existing group's all-affected-file requirement, not counted as new original hosted IDs. Recovery changes only the two reviewed fixture paths. Designated merge-manager qualification and actual new-head gates remain separate from local completion and broader main/release recovery.
Type of change
Testing
Validation
Recovery head:
125d7c4ba65f20b552b0b7a4de3e384d70ba6d4a, composed with actual public main4adaa21f5a369298e316356891d2c65181f02560using both rerere flags disabled. Parent, isolated Python child and actual installed CLI are bound to this owned Python 3.12 checkout.3b9a85036ec1665bf125d7c4baverified=true,terminal_evidence_required=true; zero touched production owners,functional_tests=[]. Regression evidence is separate.All 43 original sealed artifacts remain unchanged. The historical owner JSON passed only the semantic verifier and was not canonical-schema-valid; additive recovery evidence corrects it without invented owner rows. Earlier pytest cleanup warnings remain in historical logs. Local LF/CRLF controls are not a native Windows run; no full-suite, main-CI or release-green claim is made.
Executed recovery commands and exact results
All validation used
python3 "$GATE" --lane ci-contract-fixtures --timeout 1800 -- COMMANDwith one admitted validator.$RECOVERYis the additive session evidence directory; original evidence remains immutable..venv/bin/python "$RECOVERY/run_checks.py" restored-headran both complete integration modules:.venv/bin/python "$RECOVERY/run_checks.py" quality-head tests/quality:The admitted
.venv/bin/python "$RECOVERY/qualify.py"ran these exact checks serially at unchanged recovery head:uv run --frozen --extra dev ruff check src/ tests/ scripts/lint_architecture_boundaries.py scripts/architecture_linter/ scripts/windows_native_symlink_probe_entry.pyAll checks passed!uv run --frozen --extra dev ruff format --check src/ tests/ scripts/lint_architecture_boundaries.py scripts/architecture_linter/ scripts/windows_native_symlink_probe_entry.py2086 files already formatteduv run --frozen --extra dev python -m pylint --disable=all --enable=R0801 --min-similarity-lines=10 --fail-on=R0801 src/apm_cli/ scripts/lint_architecture_boundaries.py scripts/architecture_linter/ scripts/windows_native_symlink_probe_entry.pybash scripts/lint-auth-signals.sh[+] auth-signal lint cleanbash scripts/lint-architecture-boundaries.shgrep -Pabsence.uv run --frozen --extra dev python scripts/check_test_assertions.py[+] assertion-quality ratchet clean: AQ001=4, AQ002=12uv run --frozen --extra dev python scripts/check_exact_test_duplicates.py[+] exact test duplicate ratchet clean: 1410 files, 0 allowed duplicate group(s).venv/bin/python "$RECOVERY/collect_proof.py"Historical
1031/44/68logs/XML, baseline, failed attempts and original diagram validation remain sealed at6ec1665bf. The retained Mermaid block is byte-identical to the previouslymmdc-validated diagram.Explicit ID mappings:
test_dir_with_apm_yml_still_returns_marker_msg->test_dir_with_valid_apm_yml_returns_none.test_warn_overwrite_importerror_path->test_warn_overwrite_console_fallback, now[native],[lf],[crlf].test_installed_target_survives_audit_and_reinstall[...]IDs -> corresponding[...,lf]/[...,crlf]variants (pytest uses a final-lf/-crlfsuffix).Scenario Evidence
tests/integration/test_selective_install_mcp.py::TestSelectiveInstallTransitiveMCPIntegration::test_lockfile_records_transitive_mcp_servers(regression-trap for #3335), deep/diamond/global/update modulestests/integration/test_codex_windows_toml_install.py::test_codex_stale_cleanup_preserves_windows_literal_paths,test_mcp_integrator_characterisation.py::TestRemoveStaletests/integration/test_grok_audit_target_lifecycle.py::test_installed_target_survives_audit_and_reinstall(eight variants)tests/integration/test_govern_core_contract.pytests/integration/test_frozen_cold_cache_apm_package_e2e.pytests/integration/test_frozen_native_service_lifecycle.py::test_selected_package_install_retains_unselected_service_evidencetests/integration/test_hermetic_lifecycle_foundation.py::test_generated_artifact_tampering_reports_cause_and_recovers(five parameters)tests/integration/test_skill_integrator_hermetic.py::TestPromoteSubSkills::test_warn_overwrite_console_fallback(native/LF/CRLF)How to test
APM_BINARY_PATH="$PWD/.venv/bin/apm"andAPM_E2E_TESTS=1..venv/bin/python -m pytest -n0 -q -p no:cacheprovider tests/integration/test_grok_audit_target_lifecycle.py tests/integration/test_skill_integrator_hermetic.py; expect 60 passes, including eight lifecycle and three console newline variants.Spec conformance (OpenAPM v0.1)
If this PR changes behaviour that an OpenAPM v0.1
req-XXXcovers,confirm the three-step ritual in the
development guide:
docs/src/content/docs/specs/openapm-v0.1.mdupdated(new/changed
<a id="req-XXX"></a>anchor + prose + Appendix Crow).
docs/src/content/docs/specs/manifests/openapm-v0.1.requirements.ymlupdated.
@pytest.mark.req("req-XXX")test undertests/spec_conformance/added or extended.CONFORMANCE.{md,json}regenerated viauv run --extra dev python -m tests.spec_conformance.gen_statementand committed.
Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com