GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — fix(claude): prepare intact user plugins through native registration by danielmeppiel · Pull Request #3290 · microsoft/apm Conversation
|
| Files | Responsibility |
|---|---|
claude_plugins/admission.py, client.py, registrar.py |
Claude-specific admission, pinned metadata adapter, complete fingerprint/source-pin ownership, recovery and read-only verification. |
install/context.py, phases/claude_plugins.py, pipeline.py |
Separate native queues/phases, saved-lock handoff, lazy phase import and unchanged typed-error passthrough. |
install/deployment_plan.py, services.py, target_filter.py, target_warnings.py |
Share one native admission between batch skill preflight and integration; preserve target-specific projection, personal loose skills and retained hooks. |
install/legacy_plugin_compat.py, drift.py |
Preserve explicit normalized legacy intent; verify native source/cache fingerprints and normalize local audit sources only in scratch. |
integration/mcp_config_view.py, claude_plugins/registrar.py |
Read local Claude MCP declarations from main's install-synthesized apm_modules/_local manifest (#3540), never the publisher source; compare local lock hashes with original source snapshots independently of complete native cache fingerprints. |
integration/hook_integrator.py, hook_ownership.py |
Canonical read-only ownership inspection; preserve ordinary excluded-target cleanup. |
commands/uninstall/cli.py |
Preserve both native cleanup paths and empty-lock retry; import the existing lightweight lock-state owner without increasing the statement budget. |
.apm/architecture/owners/marketplace-plugins.json, architecture linter/tests |
Union both native owners and static mutation catalogs, including selected-format exclusion. |
| Claude component/installed-CLI tests, Codex lifecycle tests | Real routing and lifecycle regressions; existing Codex inline-MCP fixture now selects both targets. Claude metadata transport remains substituted. |
tests/spec_conformance/test_claude_cleanup_roots.py, CONFORMANCE.* |
Five retained-hook preservation cases and statements regenerated from the complete merged collection. |
Consumer/producer/reference docs and apm-usage/commands.md |
Exact scope, admission, activation ownership, recovery and unresolved runtime qualification. |
Source paths above are under src/apm_cli/ unless otherwise qualified.
The Claude reconciliation owner is the only Claude native lifecycle writer.
The generic source-plan seam and native hash API/tests are inherited from canonical main, not duplicated.
For an eligible Claude-format plugin, dashed stages show metadata writes after shared gates; failure retains intent rather than promising rollback.
flowchart LR
subgraph Shared["Shared APM admission"]
A["Resolved identity, target and executable approval"] --> B["plan_native_claude_plugin and fingerprint"]
B --> C["DeployableSourcePlan scan and retained-hook refusal"]
end
subgraph Native["Native metadata only"]
D["Saved lock, source pin and pre-write fingerprint"] --> E["Write recoverable catalog and intent"]
E --> F["Claude metadata install, update or uninstall"]
F --> G["Readback roots, activation and fingerprint"] --> H["Finalize owned ledger"]
R["Retain intent and report failure"]
end
C --> D
F -->|"metadata failure"| R
G -->|"mismatch"| R
classDef new stroke-dasharray: 5 5;
class B,D,E,F,G,H,R new;
Issue: Related #3191; shared production foundation for separately scoped #3181.
Human scope-approval comment: #3191 (comment)
Companion scope-approval comment: #3181 (comment)
Fresh immutable trusted-main7e20 governance recognizes the records but explicitly returns authorizes_implementation:false.
Current responsible-human dispatch authorizes this same-owner compatibility repair and qualified draft publication; labels/records alone are not permission.
This PR does not complete the issue. Actual three-event witnesses, effective runtime roots/resources and final native qualification remain unmet.
#3181 alone owns runtime investigation; its prior PTY stopped at normal security consent without trust, enablement or invocation.
No reviewer request, draft promotion, auto-merge, issue closure or runtime-acceptance waiver is made.
Revival at ea99d5fab (2026-11-12): merged main a14ee1521; full lint mirror clean; 9346 related + 2116 fold-rerun + 29 #3291 tests passed; CI, Spec conformance and Merge Gate green. Details: advisory. Sections below are the earlier qualification record.
Published head: d23d1acca67e569352ae89022f0cc8fcb7e42f31; integrated main: 7e20e044fb501c90279a325a278b69a72ad63367.
This merge preserves public 0d4ee809 ancestry and the same PR/branch. The command companion #3291 consumes this public pin, not a private patch.
| Resumed integration evidence | Observed result |
|---|---|
| Merged working-tree functional selection | 424 passed, including six installed-CLI lifecycle variants: three local and three pinned-Git. |
| Merged working-tree static owner selection | 120 passed. |
| Full conformance collection | 517 passed, 2 skipped; orphan check and generated statements passed. |
| Committed-head functional owner bindings | 46 passed, covering all 8 detected owners at d23d1acca. |
| Committed-head full current lint mirror | Ruff, format, three source guards, pylint R0801, auth, architecture, strict assertions and exact-test duplicates passed. |
| Four process-memory regression mutations | 10 intended failures, zero errors; guards restored before the passing functional selection. |
The broad runs used the complete merged working tree before the merge commit; they are not exact-head 0d4ee809 results. Exact-head bindings and the full mirror ran after committing d23d1acca, with a clean tree before and after.
The source guards use disclosed stdlib equivalents of CI's GNU-grep YAML/relative-path checks and its 2100-line check, not unsupported macOS grep.
Actual completion remains blocked on native acceptance. The blocked completion path does not run terminal-owner enforcement; executed owner bindings are not a readiness verdict.
CI was green at d23d1acca: CI attempt 2, Spec conformance and Merge Gate attempt 2 completed success. The first lifecycle attempt printed 394 passed, 13 skipped in 577.43s, then hit the unchanged 10-minute job deadline; its isolated retry passed in 511.37s, with a 9:05 total job duration. Original cancellation evidence remains. No timeout, selection or source change was made; cumulative CI recoveries are now 3, with historical 6/3/2 preserved separately.
All heavy commands used the parent's automatic lane3191 capacity gate.
The retained resume7e20-validate.py qualification receipt records exit 0: underlying pytest selectors produced 424/120/517 passing cases, followed by passing orphan check and generation.
The retained resume7e20-exact.py receipt records exit 0: exact selectors produced 46 passes, followed by the full current lint scope and strict guards.
The retained mutation receipt records exit 0: projection/local-hash/MCP-snapshot/replay-root mutations produced 1/1/4/4 test failures, with no setup/import errors.
uv run --frozen --extra dev ruff check src/ tests/ scripts/lint_architecture_boundaries.py scripts/architecture_linter/ scripts/windows_native_symlink_probe_entry.py: exit 0.
uv run --frozen --extra dev ruff format --check src/ tests/ scripts/lint_architecture_boundaries.py scripts/architecture_linter/ scripts/windows_native_symlink_probe_entry.py: exit 0, 2093 files already formatted.
uv 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.py: exit 0.
bash scripts/lint-auth-signals.sh and bash scripts/lint-architecture-boundaries.sh: each exit 0.
CI with APM_E2E_TESTS=1: uv run --extra dev pytest -p no:cacheprovider -q --strict-markers -n 4 --dist loadgroup --durations=20 -m 'lifecycle_smoke and not lifecycle_merge_group' tests/integration: exit 0 on retry, 394 passed / 13 skipped.
BASE_REF=origin/main bash tests/spec_conformance/mode_b_detector.sh: exit 0; spec-concurrent path delegates to the passing orphan check.
The preserved Mermaid diagram was rendered with mmdc: exit 0; extracted diagram bytes match the body.
The session-owned drivers retain each exact underlying command, JUnit/log hash and recorded revision. No native client or inference was launched.
Bounded architect and coverage reviews found no required findings in their reviewed deltas; final canonical-validator/replay adjustments were subsequently qualified, not represented as a new full-panel approval.
Prior published head: 0d4ee8095f43c241995b30c5c3b83a3c4fe50f0b; integrated base: 53ccf06d11dd2d675e8ea8c3e2523a6d321c1b79.
Ancestry preserves the prior Claude head e69283b and landed Codex main53. No rebase, force push or superseding PR.
| Exact-head evidence | Observed result |
|---|---|
| Focused Claude/Codex/owner/quality suites | 610 passed, including 68 quality cases and six installed-APM Claude variants. |
| Combined static regression selection | 31 passed. |
| Existing official Codex 0.163 metadata/content lifecycle | 6 passed, including both-target inline fixture; isolated credential-free profiles. |
| Full conformance | 348 passed, 2 skipped; orphan check, generation, Mode B and clean statements passed. |
| Actual post-mutation restoration | 81 failed test IDs passed again; source bytes and tracked tree unchanged. |
| Current CI lint scope plus strict guards | All 10 passed, including scripts/windows_native_symlink_probe_entry.py. |
| Detected owners / executed bindings | 5 owners / 13 executed passing IDs with exact head/base and JUnit hashes. |
These suites overlap; their counts are not a unique repository-wide total.
The actual completion status remains blocked, so canonical verify_completion skips terminal-owner enforcement. The separately disclosed advisory-status projection is an architecture-only probe, not an actual terminal gate or readiness pass; the five-owner/13-ID row above describes executed bindings only.
APM_QUALIFICATION_OUTPUT=../pr-3290-evidence/continuation-6-main53/candidate-3 uv run --frozen --extra dev python ../pr-3290-evidence/continuation-6-main53/run_functional.py ran the recorded affected-test selectors and full conformance: exit 0.
610 passed, 1 warning in 236.80s (0:03:56)
31 passed, 478 deselected in 92.07s (0:01:32)
6 passed in 79.72s (0:01:19)
348 passed, 2 skipped in 216.36s (0:03:36)
uv run --frozen --extra dev python ../pr-3290-evidence/continuation-6-main53/restore_mutants.py: exit 0.
81 passed in 189.84s (0:03:09)
APM_QUALIFICATION_OUTPUT=../pr-3290-evidence/continuation-6-main53/candidate-3/mirror-before-functional uv run --frozen --extra dev python ../pr-3290-evidence/continuation-6-main53/run_mirror.py: exit 0.
This executes all eight actual CI lint blocks unchanged, then strict assertion and exact-duplicate guards; all ten passed.
uv run --frozen --extra dev python -m tests.spec_conformance.orphan_check: exit 0.
uv run --frozen --extra dev python -m tests.spec_conformance.gen_statement: exit 0.
BASE_REF=origin/main bash tests/spec_conformance/mode_b_detector.sh: exit 0.
git diff --exit-code CONFORMANCE.json CONFORMANCE.md: exit 0.
These session-owned evidence drivers are not repository commands; their receipts retain each exact underlying selector, environment and JUnit hash.
The unchanged diagram was rendered again with mmdc, exit 0.
Mutation proof: 16 Claude/shared guard removals produced 40 intended failures; 41 unchanged producer Codex/API mutants produced 46 test-call failures; two additional static guard disablings produced 15 failures. Every failed ID maps to the actual 81-case post-restoration run. Five Codex failures are downstream contract exceptions, not literal AssertionErrors; none are setup/import errors or skips. Shared API source bytes were never edited, although producer guards were intentionally disabled in process memory.
Independent delta review: seven specialists reviewed the frozen initial merge tree; later folds and the final import/whitespace repairs were separately qualified at this exact head. Genuine CEO stance is ship_with_followups for qualified draft publication, not merge or runtime acceptance. Lazy phase import and existing both-target lifecycle coverage were folded. The proposed loose projection from an opaque Codex bundle was rejected; unproven replay optimization and cross-dependency failure isolation remain outside scope. Original returns and factual/coordinator corrections are retained, not rewritten.
Historical remote CI: exact-head REST verification confirmed CI 39470640291, Spec conformance 39470640316 and Merge Gate 39470640367 completed success for 0d4ee809. These are not CI results for the resumed head. CI jobs included both Linux shards/Coverage, Windows gates, lint, architecture and APM/lifecycle/binary smoke. CodeQL, Docs, NOTICE and eligibility workflows also succeeded. Original yellow-CI receipts remain untouched; this is additive evidence, not native, specification or release readiness. The historical e69283b results and prior needs_discussion stance are not relabelled.
Preserved history: failed 6d7d920 native whitespace assertion, cdde876 statement-budget failure, initial post-push readback failure and all earlier receipts remain. Historical counters at 0d4ee809 were 6/3/2, validated using the explicitly authorized session-only budget variant; no repository schema change or count reset. The resumed retry is reported separately above.
API provenance: original producer utility 5267a126 / tests 04cd8c9 were privately imported with authorship as af061529 / f3ff7a1e. They are now canonical on merged main53 and byte-identical. This continuation intentionally integrates landed Codex behavior; it does not claim only the historical API patches were imported.
Audit/runtime boundary: the prior raw-local MCP consistency failure is fixed at d23d1acca; local frozen install and aggregate audit now pass the installed-CLI contract with substituted metadata transport. Historical real Claude 2.1.291 registrar evidence remains metadata-only and was not rerun. POSIX executable evidence is not new Windows runtime qualification.
| Scenario | Principle | Executed test |
|---|---|---|
| Intact hooks/resources without loose Claude projection | Multi-harness support | tests/unit/install/test_claude_native_hooks.py::test_native_hooks_remain_intact_without_loose_settings |
| Retained owned/unreadable hook state refuses native transition without deletion | Secure by default | tests/spec_conformance/test_claude_cleanup_roots.py::test_native_transition_preserves_retained_target_hook_state (five cases) |
| Missing approval, unsafe tree and actual skill subsets refuse admission | Governed by policy | tests/unit/install/test_claude_native_hooks.py::test_hook_denial_does_not_register_a_commands_only_subset; tests/unit/install/test_claude_native_admission.py |
| Full byte/mode fingerprint, same-pin refusal and read-only audit | Secure by default | tests/unit/install/test_claude_native_registration.py::test_complete_native_bundle_drift_is_not_legacy_hash_equivalence; same file's test_local_native_audit_checks_source_and_live_cache_without_repairing_either |
| Removal/retry and original ownership survive failures | DevX | tests/unit/install/test_claude_native_registration.py::test_legacy_native_ownership_requires_explicit_removal_before_attestation; tests/integration/test_claude_native_hook_lifecycle.py::test_installed_hook_source_reinstall_and_removal |
| Both targets preserve native-format ownership | Multi-harness support | tests/unit/install/test_claude_native_hooks.py::test_native_admission_keeps_selected_format_owner_with_both_targets; tests/integration/test_codex_native_plugin_lifecycle.py::test_installed_cli_registers_complete_codex_bundle_disabled[inline] |
| A same-name personal loose skill survives native install and removal | DevX | tests/unit/install/test_claude_native_hooks.py::test_prepared_native_plan_preserves_unmanaged_loose_skill; six installed lifecycle variants |
| Local plugin MCP inspection preserves publisher bytes and never waives a missing synthesized manifest | Secure by default | tests/unit/integration/test_mcp_config_view.py::test_local_claude_source_is_never_mutated_or_waived_during_mcp_inspection (eight cases) |
| Local source hashes and native-cache tampering are checked independently | Secure by default | tests/unit/install/test_claude_native_registration.py::test_local_lock_hash_and_admitted_cache_fingerprint_are_independent; local audit tamper cases |
tests/spec_conformance with workspace-owned fixture paths; expect the results above.${CLAUDE_PLUGIN_ROOT} is rewritten in hooks but not in commands #3181; this description does not authorize trust, activation, invocation or another native probe.If this PR changes behaviour that an OpenAPM v0.1 req-XXX covers,
confirm the three-step ritual in the
development guide:
docs/src/content/docs/specs/openapm-v0.1.md updated<a id="req-XXX"></a> anchor + prose + Appendix Cdocs/src/content/docs/specs/manifests/openapm-v0.1.requirements.yml@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_statementNot N/A: observable behavior changes, but this repair preserves existing target, selection, integrity, authorization, retained-hook and canonical source-plan constraints.
The retained-hook transition complies with req-lk-021; no normative waiver is required.
Five executable preservation cases cover owned state, orphaned ownership, malformed config/sidecar and non-object JSON. Statements were regenerated from the complete collection.
The native fingerprint is target-specific ownership metadata; ordinary lock hashing remains canonical. Claude replay uses its complete verifier instead of copying source into loose deployment roots. No normative text or manifest changes were authored by this PR.
req-tg-013 remains schema-bearing Agent Plugins v1 only; raw Claude metadata does not claim that atomic-registration contract. Implementation-specific external formats are not exempt from consumer safety.
Remaining acceptance boundary: actual Claude runtime witnesses and consent are absent. Neither conformance, metadata qualification nor CI authorizes draft promotion, issue closure or merge.
Co-authored-by: Copilot [email protected]
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Register new plugins disabled via the qualified native CLI, preserve activation, and reconcile owned metadata from locked sources. Authenticated runtime qualification remains pending. Co-authored-by: Copilot App <[email protected]> Copilot-Session: 6c656434-efdf-444d-bb89-27407cbc7c44
Read saved lock state, preserve parser-normalized legacy plugin types, and retain selector/preflight ownership while suppressing loose projection. Co-authored-by: Copilot App <[email protected]> Copilot-Session: 6c656434-efdf-444d-bb89-27407cbc7c44
Cover user-hook migration, standalone and replay controls, full-source safety, interrupted ownership recovery and native transport metadata exclusion. Document qualified metadata versus pending runtime execution. Co-authored-by: Copilot App <[email protected]> Copilot-Session: 6c656434-efdf-444d-bb89-27407cbc7c44
Co-authored-by: Copilot App <[email protected]> Copilot-Session: 6c656434-efdf-444d-bb89-27407cbc7c44
Fold independent PR3290 panel findings and observed CI failures. Exercise installed APM hook metadata lifecycle without native hook execution. Preserve canonical empty survivors until native cleanup succeeds, keep target-aware diagnostics, and document the missing runtime witnesses. Metadata protocol fixture extracted from Daniel Meppiel's command lifecycle test in commit 41bdcf1, preserving its metadata-only boundary. Co-authored-by: Daniel Meppiel <[email protected]> Co-authored-by: Copilot App <[email protected]> Copilot-Session: f79e464c-180e-4be3-9056-0773aa679a1a
Co-authored-by: Copilot App <[email protected]> Copilot-Session: f79e464c-180e-4be3-9056-0773aa679a1a # Conflicts: # src/apm_cli/install/drift.py
Co-authored-by: Copilot App <[email protected]> Copilot-Session: f79e464c-180e-4be3-9056-0773aa679a1a
Co-authored-by: Copilot App <[email protected]> Copilot-Session: f79e464c-180e-4be3-9056-0773aa679a1a
Refuse unsupported automatic migration through the existing hook owner. Exercise req-lk-021 byte preservation and malformed-state refusal with real component conformance cases; keep native runtime qualification open. Co-authored-by: Copilot App <[email protected]> Copilot-Session: f79e464c-180e-4be3-9056-0773aa679a1a
Preserve retained-hook compliance and the canonical native replay seam. Co-authored-by: Copilot App <[email protected]> Copilot-Session: f79e464c-180e-4be3-9056-0773aa679a1a
Keep existing package and lockfile hash semantics unchanged. Provide one canonical raw-content and Git executable-bit fingerprint for native consumers. Co-authored-by: Copilot App <[email protected]> Copilot-Session: f79e464c-180e-4be3-9056-0773aa679a1a
Exercise complete publisher assets, Git executable bits, transport exclusions, symlink refusal, and unchanged historical package hashes without any native runtime. Co-authored-by: Copilot App <[email protected]> Copilot-Session: f79e464c-180e-4be3-9056-0773aa679a1a
Use the sole canonical native fingerprint API for admission, retained ownership, readback and read-only audit. Bind remote attestations to saved source pins, refuse unfingerprinted legacy adoption, and retain recoverable removal intent. Normalize local replay inputs only in scratch. Co-authored-by: Copilot App <[email protected]> Copilot-Session: f79e464c-180e-4be3-9056-0773aa679a1a
Exercise missing pins, independently callable pre-write checks, mixed-version removal recovery, normalization stability and real local CLI audit. Keep the pre-existing local MCP consistency diagnostic distinct from native drift evidence. Document audit scope and retained fingerprint boundaries. Co-authored-by: Copilot App <[email protected]> Copilot-Session: f79e464c-180e-4be3-9056-0773aa679a1a
Fold the independent CEO synthesis follow-up without weakening the generic MCP source-admission contract. Raw local legacy plugins can retain a separate config-consistency failure while their native fingerprint is healthy. Co-authored-by: Copilot App <[email protected]> Copilot-Session: f79e464c-180e-4be3-9056-0773aa679a1a
There was an error while loading. Please reload this page.
APM Review Panel:
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Preserve both native registrars, selected-format admission, audit replay and cleanup. Retain canonical native hashing and source-plan authority; cover combined target selection and defer the Claude phase import. Co-authored-by: Copilot App <[email protected]> Copilot-Session: f79e464c-180e-4be3-9056-0773aa679a1a
The exact merged candidate emitted the required user-scope refusal, but Rich wrapped the phrase across a line. Normalize diagnostic whitespace while retaining the failure, wording and unchanged-native-state assertions. Co-authored-by: Copilot App <[email protected]> Copilot-Session: f79e464c-180e-4be3-9056-0773aa679a1a
Keep dynamic function lookup through the existing pure lockfile_state owner. This removes a redundant function-local import and restores the unchanged 200-statement budget after the native merge, without changing cleanup or refusal behavior. Co-authored-by: Copilot App <[email protected]> Copilot-Session: f79e464c-180e-4be3-9056-0773aa679a1a
Share prepared native admission with batch skill preflight, verify local locks against the original source image, and inspect raw local MCP declarations in disposable validated snapshots. Keep Claude audit verification isolated from loose deployment replay and preserve independent cache fingerprints. Co-authored-by: Copilot App <[email protected]> Copilot-Session: 6c656434-efdf-444d-bb89-27407cbc7c44
Integrate published #3290 d23d1ac and main 7e20 while preserving the independent #3181 command contracts and contributor ancestry. Native runtime acceptance remains unmet; this merge does not grant consent. Co-authored-by: Copilot App <[email protected]> Copilot-Session: 583dd1bc-30be-41e1-b45e-a1dd8988136e
|
Published The resumed repair shares native admission with batch skill preflight, preserves same-name personal loose skills, checks local locks against original source snapshots, validates raw local MCP declarations in disposable scratch, and keeps complete Claude audit verification out of loose-deployment replay. The command companion #3291 consumed this public foundation; no private producer patch was required. Evidence: 424 functional and 120 static passes on the merged working tree; full conformance 517 passed / 2 skipped; 46 exact-head functional cases bind all 8 detected owners; full current lint mirror and strict guards pass. Four process-memory guard mutations produced 10 intended failures with zero errors before restoration. Current CI, spec conformance, and Merge Gate are successful at this head. The original lifecycle job completed 394 tests successfully, with 13 skips, then hit its 10-minute job deadline. Its one isolated retry passed in 511.37 seconds / 9:05 total job time. No timeout, selection or source was changed. The original cancellation remains recorded; historical 6/3/2 is preserved, with cumulative CI recoveries now 3. Acceptance remains blocked, not ready to merge. Normal native consent for the isolated owned fixture session is still absent. Actual Claude Code 2.1.291 Generated by autopilot-pr-merge-worker. This comment is AI-generated and may contain errors. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Resolve two conflicts while keeping main's behavior and this PR's native Claude registration owner: - uninstall: keep main's _persist_uninstall_lockfile (symlink refusal, committed-claim binding, profile-scoped updates) and extend it with defer_empty_removal so an empty last-package lock is still retained until Claude native cleanup converges, then removed. - mcp_config_view: adopt main's #3540 redirect to the install-synthesized apm_modules/_local manifest for local Claude plugins (with missing-manifest warning and frozen cold-cache deferral). Drop the superseded scratch snapshot and retarget the marketplace-integrations-claude-ownership static guard and its mutation cases to main's redirect. Co-authored-by: Copilot App <[email protected]>
- Route uninstall lock persistence through main's guarded _persist_uninstall_lockfile call; a small helper persists survivors, converges native registrations, then removes an empty last-package lock, keeping uninstall() within its statement budget. - Extract _queue_native_claude so integrate_package_primitives stays within the C901 limit after combining main's changes. - Align the local Claude MCP read-only test with main's #3540 semantics: without the install-synthesized manifest, servers stay uncollected and the publisher source is never mutated. Co-authored-by: Copilot App <[email protected]>
Fold delta-panel follow-ups on the merge resolution: - _persist_lock_then_resync_native takes deploy_root, modules_dir and scope explicitly instead of forwarding **kwargs. - Unit traps for _persist_uninstall_lockfile defer_empty_removal branches and for removing an empty last-package lock only after native resync converges (mutation-break: no-defer -> 3 failures, unlink-before-resync -> 2 failures). Co-authored-by: Copilot App <[email protected]>
Native Claude check (10 minutes)This is the merge gate for #3181: Claude Code itself must load the plugin APM registered and run its namespaced command, with Requirements: macOS or Linux, 1. Isolated tools (about 3 minutes)export CHECK="$(mktemp -d /tmp/apm-native-claude-check.XXXXXX)" export SHA="$(git ls-remote https://github.com/microsoft/apm refs/heads/danielmeppiel-claude-command-qualification | cut -f1)" echo "check dir: $CHECK stack head: $SHA" # Claude Code 2.1.291 is the only version APM's native route is qualified for. npm install --silent --prefix "$CHECK/npm" @anthropic-ai/[email protected] # APM from the #3290 + #3291 stack head. if ! { uv venv -q "$CHECK/apm-venv" && uv pip install -q --python "$CHECK/apm-venv/bin/python" "git+https://github.com/microsoft/apm@$SHA"; }; then # Fallback if uv cannot resolve from your index: run the stack source with # the .venv of an existing microsoft/apm checkout. export APM_REPO="$HOME/Repos/awd-cli" git -C "$APM_REPO" fetch -q origin danielmeppiel-claude-command-qualification git -C "$APM_REPO" worktree add -q --detach "$CHECK/apm-src" "$SHA" mkdir -p "$CHECK/apm-venv/bin" printf '#!/bin/sh\nPYTHONPATH="%s/apm-src/src" exec "%s/.venv/bin/python" -m apm_cli.entrypoint "$@"\n' "$CHECK" "$APM_REPO" > "$CHECK/apm-venv/bin/apm" chmod +x "$CHECK/apm-venv/bin/apm" fi "$CHECK/apm-venv/bin/apm" --version # the version line ends with the first 9 chars of $SHA 2. Isolated HOME and CLAUDE_CONFIG_DIRexport REAL_HOME="$HOME" export HOME="$CHECK/home" export CLAUDE_CONFIG_DIR="$CHECK/home/.claude" export PATH="$CHECK/npm/node_modules/.bin:$CHECK/apm-venv/bin:$PATH" mkdir -p "$HOME/.apm" "$CHECK/work" claude --version # expect: 2.1.291 (Claude Code) 3. Install the fixture plugin globally with APMcat > "$HOME/.apm/apm.yml" <<EOF name: native-claude-check version: 1.0.0 targets: [claude] dependencies: apm: - git: microsoft/apm ref: $SHA path: tests/fixtures/native_claude_commands EOF (cd "$CHECK/work" && apm install -g --target claude --only apm) Expected output includes: claude plugin list --json ls "$CLAUDE_CONFIG_DIR/commands" 2>&1 # expect: No such file or directory (no loose copies) Expected: exactly one entry, 4. Your consent: enable the pluginAPM never enables plugins. You do that: claude plugin enable apm-command-context@apm-claude --scope user5. Run the namespaced command in a real sessioncd "$CHECK/work" APM_COMMAND_PROBE_MARKER="$CHECK/witness.jsonl" claude In Claude:
{"root":"<CHECK>/home/.claude/plugins/cache/apm-claude/apm-command-context/1.0.0","resource":"APM_NATIVE_COMMAND_CONTEXT","argument":"qualified-3181"}
6. Verify the witness (proof of success)python3 - "$CHECK" <<'PY' import json, pathlib, sys check = pathlib.Path(sys.argv[1]).resolve() rows = [json.loads(l) for l in (check / "witness.jsonl").read_text().splitlines() if l.strip()] assert len(rows) == 1, rows row = rows[0] assert row["resource"] == "APM_NATIVE_COMMAND_CONTEXT", row assert row["argument"] == "qualified-3181", row root = pathlib.Path(row["root"]).resolve() assert root.is_relative_to(check / "home"), root assert (root / "scripts/context.mjs").is_file() and (root / "resources/identity.txt").is_file(), root print("[+] NATIVE CLAUDE CHECK PASSED") print(" root:", root) PY Success means the script prints Failure looks like one of these: Heads-up from the agent dry run: 7. Clean up(cd "$CHECK/work" && apm uninstall -g microsoft/apm/tests/fixtures/native_claude_commands) claude plugin list --json # expect: [] export HOME="$REAL_HOME"; unset CLAUDE_CONFIG_DIR [ -n "${APM_REPO:-}" ] && git -C "$APM_REPO" worktree remove --force "$CHECK/apm-src" rm -rf "$CHECK" Then open a new shell so What the agent already verified at stack head Generated by autopilot-pr-merge-worker. This comment is AI-generated and may contain errors. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
APM Review Panel (delta):
|
| PR | head SHA | CEO stance | iters | folds | defers | Copilot rounds | CI | mergeable | mergeStateStatus | notes |
|---|---|---|---|---|---|---|---|---|---|---|
| #3290 | ea99d5f | needs_discussion | 1 | 2 | 2 | 1 (0 items) | green | MERGEABLE | BLOCKED | Ready for review; do not merge until Daniel's native check passes |
| #3291 | 73a2550 | n/a | - | - | - | - | stacked | MERGEABLE | - | Stays draft until Daniel confirms |
No merge, auto-merge, reviewer request, assignment or issue closure.
Generated by autopilot-pr-merge-worker. This comment is AI-generated and may contain errors.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Critical reconciliation, migration, and persistence flaws can remove authorized Claude registrations, lose activation choices, duplicate loaded content, and mutate native state without saving recovery data.
This PR adds intact native registration for eligible global Claude plugins, addressing missing hook resources and plugin-root context from #3191. It reuses APM's acquisition, authorization, scanning and lockfile infrastructure. Registration remains metadata-only; actual hook and command execution is still unqualified.
Changes:
| File | Description |
|---|---|
tests/utils/claude_native_protocol.py |
Adds a metadata-only Claude transport substitute. |
tests/unit/test_deployment_materialization_receipts.py |
Tests empty-lock retention during native cleanup. |
tests/unit/scripts/test_architecture_runner.py |
Includes the Claude ownership rule. |
tests/unit/integration/test_mcp_config_view.py |
Checks read-only local-plugin MCP inspection. |
tests/unit/install/test_legacy_plugin_compat.py |
Tests normalized plugin intent preservation. |
tests/unit/install/test_claude_native_registration.py |
Covers registration, integrity, activation and recovery. |
tests/unit/install/test_claude_native_hooks.py |
Tests native routing and loose-content preservation. |
tests/unit/install/test_claude_native_admission.py |
Tests capability, selection and source-safety gates. |
tests/spec_conformance/test_claude_cleanup_roots.py |
Adds retained-hook preservation cases. |
tests/integration/test_codex_native_plugin_lifecycle.py |
Exercises Codex registration with both targets selected. |
tests/integration/test_claude_native_hook_lifecycle.py |
Tests installed-CLI lifecycle with substituted metadata transport. |
tests/integration/test_architecture_skill_preflight.py |
Updates shared deployment-plan mutation checks. |
tests/integration/test_architecture_owner_rule_mutations.py |
Adds Claude ownership and integrity mutations. |
tests/integration/test_architecture_native_plugin_audit.py |
Updates native audit routing mutation coverage. |
src/apm_cli/integration/hook_ownership.py |
Adds shared read-only hook-object parsing. |
src/apm_cli/integration/hook_integrator.py |
Adds dry-run hook cleanup inspection. |
src/apm_cli/install/target_warnings.py |
Receives existing executable-skip warnings. |
src/apm_cli/install/target_filter.py |
Receives hook reconciliation diagnostics. |
src/apm_cli/install/services.py |
Queues Claude plugins and checks retained hooks. |
src/apm_cli/install/pipeline.py |
Runs Claude registration after shared gates. |
src/apm_cli/install/phases/claude_plugins.py |
Hands saved lock state to Claude reconciliation. |
src/apm_cli/install/legacy_plugin_compat.py |
Preserves normalized marketplace-plugin classification. |
src/apm_cli/install/drift.py |
Adds Claude fingerprint verification and scratch normalization. |
src/apm_cli/install/deployment_plan.py |
Shares native admission and projection decisions. |
src/apm_cli/install/context.py |
Stores admitted Claude plugin plans. |
src/apm_cli/commands/uninstall/cli.py |
Adds Claude cleanup and deferred empty-lock removal. |
src/apm_cli/claude_plugins/registrar.py |
Owns Claude catalog, ledger and lifecycle reconciliation. |
src/apm_cli/claude_plugins/client.py |
Adds version-pinned metadata-only CLI transport. |
src/apm_cli/claude_plugins/admission.py |
Validates complete plugins and fingerprints sources. |
src/apm_cli/claude_plugins/__init__.py |
Introduces the Claude native package. |
scripts/architecture_linter/checks/marketplace_package_and_registration.py |
Enforces Claude ownership and shared routing boundaries. |
packages/apm-guide/.apm/skills/apm-usage/commands.md |
Documents native installation, audit and recovery. |
docs/src/content/docs/reference/package-types.md |
Explains intact Claude plugin eligibility. |
docs/src/content/docs/reference/cli/uninstall.md |
Documents native cleanup and recovery locks. |
docs/src/content/docs/reference/cli/install.md |
Documents client requirements and rollback limits. |
docs/src/content/docs/producer/author-primitives/hooks-and-commands.md |
Explains native hook preservation and migration limits. |
docs/src/content/docs/consumer/installing-from-marketplaces.md |
Details native scope, integrity and qualification limits. |
CONFORMANCE.md |
Updates retained-hook requirement coverage counts. |
CONFORMANCE.json |
Records five new retained-hook conformance cases. |
.apm/architecture/owners/marketplace-plugins.json |
Registers the Claude native lifecycle owner. |
Review effort: Balanced
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| if plan is None: | ||
| continue |
| empty = persist and bool( | ||
| _persist_uninstall_lockfile(lockfile, lockfile_path, logger, integration_cleanup) | ||
| ) | ||
| _resync_native_registration_after_uninstall( |
| """Use the same reconciliation owner as removal, with scanned new plans.""" | ||
| if ctx.apm_modules_dir is None: | ||
| return | ||
| resync_claude_plugins( |
| _check_bundle_fingerprint(plugin.source_root, plugin.bundle_hash) | ||
| desired[plugin_id] = entry | ||
|
|
||
| client = ClaudePluginCLI() |
At least 0 approving reviews are required to merge this pull request.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.