Skip to content

refactor: files_adopted follow-ups from PR #1313 review panel#1617

Merged
danielmeppiel merged 3 commits into
mainfrom
danielmeppiel/1314-files-adopted-followups
Jun 2, 2026
Merged

refactor: files_adopted follow-ups from PR #1313 review panel#1617
danielmeppiel merged 3 commits into
mainfrom
danielmeppiel/1314-files-adopted-followups

Conversation

@danielmeppiel

Copy link
Copy Markdown
Collaborator

TL;DR

Implements all 6 code-change follow-ups from the review panel on PR #1313
(issue #1314). Item 7 (growth narrative) is explicitly out of scope for
this PR.

Problem (WHY)

PR #1313 fixed the files_adopted catch-22 bug but the review panel
identified 6 clean-up items: a shared helper for the adopt predicate,
a naming-consistency rename, a recovery hint in the error message, a missing
unit test class, and a proof-of-self-healing in the E2E test.

Approach (WHAT)

  • Item 2 (E2E third run): Add a third apm install (without
    --no-policy) to test_required_packages_deployed_passes_after_lockfile_wipe
    to prove the full pipeline self-heals.

  • Item 3 (try_adopt_identical): Add BaseIntegrator.try_adopt_identical()
    static helper that encapsulates the 3-line adopt pattern. Update 6
    secondary call sites (agent x3, prompt x1, hook x2).

  • Item 4 (_dirs_equal rename): Rename SkillIntegrator._dirs_equal to
    is_skill_dir_identical_to_source for naming consistency with
    is_content_identical_to_source. Update all test references.

  • Item 5 (--no-policy hint): Append recovery hint to the
    required-packages-deployed failure message so users in the catch-22
    know how to self-heal without reading docs.

  • Item 6 (CommandIntegrator test): Add TestCommandIntegratorAdopt unit
    test class proving the adopt check fires before format dispatch in
    integrate_commands_for_target.

  • Item 3 (test): Add TestTryAdoptIdentical unit tests for the new
    static helper.

Validation evidence

  • All 118 unit tests in affected test files pass
  • 51 skill integrator hermetic tests pass with renamed method
  • Full lint gate passes: ruff check, ruff format, pylint R0801, auth-signal lint
  • 15,916 tests pass in full suite run (1 flaky unrelated test excluded)

Closes #1314

…y hint

Items from review panel on PR #1313 (issue #1314):

- Add BaseIntegrator.try_adopt_identical() static method that encapsulates
  the is_content_identical_to_source + append pattern so secondary call
  sites share a single predicate call instead of 3-line blocks (item 3)

- Update secondary call sites in agent_integrator (x3), prompt_integrator,
  hook_integrator (x2) to use try_adopt_identical instead of inline pattern

- Rename SkillIntegrator._dirs_equal -> is_skill_dir_identical_to_source
  for naming consistency with is_content_identical_to_source (item 4)

- Append --no-policy recovery hint to required-packages-deployed failure
  message so users in the catch-22 know how to self-heal (item 5)

- Add TestCommandIntegratorAdopt unit tests proving the adopt check fires
  before format dispatch in integrate_commands_for_target (item 6)

- Add TestTryAdoptIdentical unit tests for the new static helper

- Add test_fail_message_includes_no_policy_hint to policy check tests

- Add third install run (without --no-policy) to the E2E test proving
  the full pipeline self-heals after a lockfile wipe (item 2)

- Update all test references to _dirs_equal to the new name

Closes #1314

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 2, 2026 16:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Follow-up refactor/test improvements for the files_adopted + “silent adopt” recovery work from #1313/#1314, including a new shared helper for the adopt predicate, a SkillIntegrator rename for naming symmetry, improved policy failure UX, and additional unit/E2E coverage to prove self-healing behavior.

Changes:

  • Add BaseIntegrator.try_adopt_identical() and refactor multiple integrator call sites to use it.
  • Rename SkillIntegrator._dirs_equal to SkillIntegrator.is_skill_dir_identical_to_source and update several tests accordingly.
  • Improve required-packages-deployed failure message with a --no-policy recovery hint and add tests (unit + E2E) to verify behavior.
Show a summary per file
File Description
tests/unit/policy/test_policy_checks.py Adds a unit test asserting the --no-policy hint is present in the required-packages-deployed failure message.
tests/unit/integration/test_content_identical_adopt.py Adds unit coverage for try_adopt_identical and CommandIntegrator adopt behavior; updates narrative to new SkillIntegrator method name.
tests/integration/test_wave6_integrators_coverage.py Updates SkillIntegrator directory-equality tests to call the renamed method.
tests/integration/test_skill_integrator_hermetic.py Updates hermetic SkillIntegrator directory-equality tests to call the renamed method.
tests/integration/test_silent_adopt_existing_files_e2e.py Adds a third install run (with policy enabled) to prove end-to-end self-healing.
tests/integration/test_integrators_phase3.py Updates SkillIntegrator directory-equality tests and header comment for the rename.
src/apm_cli/policy/policy_checks.py Appends a concrete recovery hint to the required-packages-deployed policy failure message.
src/apm_cli/integration/skill_integrator.py Renames _dirs_equal to is_skill_dir_identical_to_source and updates the promote logic to call the new name.
src/apm_cli/integration/prompt_integrator.py Refactors adopt predicate usage to try_adopt_identical.
src/apm_cli/integration/hook_integrator.py Refactors adopt predicate usage to try_adopt_identical at two call sites.
src/apm_cli/integration/base_integrator.py Adds try_adopt_identical helper on BaseIntegrator.
src/apm_cli/integration/agent_integrator.py Refactors multiple adopt predicate call sites to try_adopt_identical.

Copilot's findings

Comments suppressed due to low confidence (1)

src/apm_cli/integration/skill_integrator.py:514

  • Renaming _dirs_equal to is_skill_dir_identical_to_source breaks remaining callers that still invoke SkillIntegrator._dirs_equal(...) (e.g. tests/integration/test_integrators_end_to_end.py and tests/integration/test_skill_integrator_phase3w4.py). This will raise AttributeError and fail the integration test suite unless every reference is updated in the same PR or a backward-compat alias is kept.
    @staticmethod
    def is_skill_dir_identical_to_source(dir_a: Path, dir_b: Path) -> bool:
        """Check if two directory trees have identical file contents."""
        dcmp = filecmp.dircmp(str(dir_a), str(dir_b))
        return SkillIntegrator._dircmp_equal(dcmp)

  • Files reviewed: 12/12 changed files
  • Comments generated: 2

Comment on lines +238 to +241
@staticmethod
def try_adopt_identical(target_path: Path, source_path: Path, target_paths: list) -> bool:
"""Adopt *target_path* when it is byte-identical to *source_path*.

Comment on lines +499 to +501
# ---------------------------------------------------------------------------
# CommandIntegrator copilot-target adopt (issue #1314, item 6)
# ---------------------------------------------------------------------------
- Update required-packages-deployed hint from 're-run with --no-policy'
  to full literal 'apm install --no-policy' for zero-friction copy-paste
- Use repair framing instead of bypass framing
- Add CHANGELOG [Unreleased] Fixed entry for the user-visible hint

Panel fold from apm-review-panel: cli-logging-expert, devx-ux-expert,
oss-growth-hacker, doc-writer (all folded, others deferred).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel

Copy link
Copy Markdown
Collaborator Author

APM Review Panel: ship_with_followups

Closes the files_adopted catch-22 by extracting try_adopt_identical, renaming for clarity, and adding a self-service --no-policy recovery hint -- all with proportionate test coverage and zero security regression.

cc @danielmeppiel @sergio-sisternes-epam -- a fresh advisory pass is ready for your review.

The panel converged cleanly. Python-architect confirms the Extract Method refactor is sound; supply-chain-security confirms no symlink-race or guard regressions; test-coverage-expert validates that all behavioral changes carry regression-trap tests at the unit+fixture tier. CI is green across the board.

The one substantive tension is between the doc-writer's concern (the --no-policy hint frames a break-glass mechanism as routine repair) and the oss-growth-hacker's observation (that exact framing is a retention win). The CEO sides with shipping the hint as-is: the user is already in a broken state when they see this message, and telling them how to recover is correct UX. However, the docs in policy-pilot.md should be reconciled in a follow-up so the corpus speaks with one voice -- the hint is accurate, the docs framing is aspirational, and the two need alignment, not a revert of the hint.

The CHANGELOG gap is a process gap, not a code defect -- already folded into this branch before this comment was posted.

Dissent. doc-writer vs. oss-growth-hacker on --no-policy hint tone: doc-writer sees break-glass dilution, growth-hacker sees retention-saving self-service. The CEO sides with growth-hacker for the runtime message and with doc-writer for the docs corpus -- reconcile in a follow-up PR that updates policy-pilot.md framing.

Aligned with: Governed-by-policy (--no-policy preserves CI enforcement; it only unblocks the local loop). Pragmatic-as-npm (converting a dead-end error into a copy-paste fix command is the ergonomic bar we target). OSS-community-driven (closes #1314 with clean refactor and full test coverage).

Growth signal. The --no-policy catch-22 fix is a silent-churn prevention win. When the narrative item lands, this becomes a concrete story beat: APM detects broken state and tells you exactly how to fix it. Worth tracking for the next release note.

Panel summary

Persona B R N Takeaway
Python Architect 0 1 1 Clean refactor that correctly applies Extract Method. Architectural layering is sound.
CLI Logging Expert 0 0 1 Hint message follows Rule 4 (include the fix). Minor naming nit -- folded.
DevX UX Expert 0 0 2 Recovery hint for required-packages-deployed is sound UX; minor polish on wording -- folded.
Supply-Chain Security Expert 0 0 1 No supply-chain regression; try_adopt_identical preserves symlink-race guards.
OSS Growth Hacker 0 0 1 --no-policy hint converts dead-end error into self-service escape hatch.
Doc Writer 0 2 0 Active via fallback: user-visible error string changed. Hint framing vs. docs corpus needs a follow-up; CHANGELOG gap folded.
Test Coverage Expert 0 0 1 All behavioral changes have regression-trap tests at unit tier with real fixtures.

B = blocking-severity findings, R = recommended, N = nits.
Counts are signal strength, not gates. The maintainer ships.

Top 2 follow-ups (2 of 4 already folded into this branch)

  1. [Doc Writer] Reconcile policy-pilot.md break-glass framing with the new recovery hint's routine-repair tone. -- The docs corpus and runtime messages should speak with one voice; currently the hint implies normalcy while policy-pilot.md implies last-resort. (Deferred: different scope from this refactor PR)
  2. [Python Architect] Evaluate whether try_adopt_identical should delegate to _check_adopt_or_skip internally to prevent future drift. -- Two-line overlap is not a regression today but signals potential duplication drift as more integrators land. (Deferred: deeper BaseIntegrator redesign)

Folded into this branch: CHANGELOG entry (doc-writer) + hint text polished to full apm install --no-policy literal command (cli-logging-expert/devx-ux-expert/oss-growth-hacker).

Recommendation

Merge now. The refactor is architecturally sound, security-clean, and fully tested. The two remaining follow-ups (CHANGELOG framing alignment in policy-pilot.md and try_adopt_identical delegation) should land in separate PRs -- neither justifies blocking a green CI result on a community-filed issue fix.


Full per-persona findings

Python Architect

  • [recommended] try_adopt_identical has a 2-line overlap with _check_adopt_or_skip; consider whether try_adopt_identical should delegate internally to prevent future drift between the two paths.
  • [nit] Type annotation in try_adopt_identical could be tightened to list[Path] instead of bare list.

CLI Logging Expert

  • [nit] Hint text was polished to include the full literal command -- folded into this branch.

DevX UX Expert

  • [nit] Hint could include a literal copy-paste command for zero-friction recovery -- folded (hint now reads: apm install --no-policy).
  • [nit] Backtick-quoting of --no-policy flag was inconsistent -- folded.

Supply-Chain Security Expert

  • [nit] --no-policy hint could note that CI enforcement is unaffected by the flag. (Informational; not folded to avoid bloating the error message.)

OSS Growth Hacker

  • [nit] Recovery hint wording could use repair framing rather than bypass framing -- folded (hint now says "repair the lockfile").

Doc Writer

  • [recommended] New error hint frames --no-policy as routine lockfile-repair, contradicting policy-pilot.md which states "Treat it as break-glass." Recommend a follow-up PR to align docs framing.
  • [recommended] No CHANGELOG entry for the user-visible error-message change -- folded into this branch.

Auth Expert -- inactive

No auth surface (token management, credential resolution, host classification) affected.

Test Coverage Expert

  • [nit] E2E integration test for adopt flow requires GITHUB_APM_PAT so outcome is unknown in CI; the unit+fixture tier already meets the floor for this change.

This panel is advisory. It does not block merge. Re-apply the
panel-review label after addressing feedback to re-run.

@danielmeppiel danielmeppiel merged commit 1c6e3a8 into main Jun 2, 2026
10 checks passed
@danielmeppiel danielmeppiel deleted the danielmeppiel/1314-files-adopted-followups branch June 2, 2026 18:10
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.

Follow-ups from apm-review-panel on #1313 (adopt byte-identical files)

2 participants