Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
212b59f
fix(install): fail positional total validation
danielmeppiel Jul 10, 2026
c498905
fix(hooks): emit Copilot hook schema version
danielmeppiel Jul 10, 2026
7f42588
fix(compile): clean after last primitive removal
danielmeppiel Jul 10, 2026
fc027a4
fix(install): support external Claude config root
danielmeppiel Jul 10, 2026
518bad9
fix(install): avoid interrupted summary on validation failure
danielmeppiel Jul 10, 2026
fb904c0
test(install): tighten total-validation exit assertion
danielmeppiel Jul 10, 2026
da9b48d
docs(changelog): note positional install exit fix
danielmeppiel Jul 10, 2026
a035658
Merge origin/main into apm-rt-fix-2126
danielmeppiel Jul 10, 2026
fbfc9f0
test(hooks): preserve explicit Copilot version
danielmeppiel Jul 10, 2026
8cbd7b3
Merge remote-tracking branch 'origin/main' into apm-rt-fix-2128
danielmeppiel Jul 10, 2026
969ccc9
test(install): loosen validator call-count coupling
danielmeppiel Jul 10, 2026
dd86f66
chore: retrigger dropped PR checks
danielmeppiel Jul 10, 2026
42af7a6
test(hooks): verify version through install dispatch
danielmeppiel Jul 10, 2026
ac78b8f
Merge latest origin/main into apm-rt-fix-2126
danielmeppiel Jul 10, 2026
fbc2e84
Merge remote-tracking branch 'origin/main' into apm-rt-fix-2128
danielmeppiel Jul 10, 2026
cf8c807
Merge origin/main for CI parity
danielmeppiel Jul 10, 2026
959127c
fix(compile): fold cleanup review findings
danielmeppiel Jul 10, 2026
0d26e31
Merge origin/main into apm-rt-fix-2129
danielmeppiel Jul 10, 2026
5c7aa93
fix(install): fold external Claude root review
danielmeppiel Jul 10, 2026
d366a8c
fix(compile): align empty-output guards
danielmeppiel Jul 10, 2026
a7af5d8
docs(security): clarify managed deployment roots
danielmeppiel Jul 10, 2026
077fd20
fix(compile): clarify clean-only completion
danielmeppiel Jul 10, 2026
608f36c
fix(compile): advertise all accepted targets
danielmeppiel Jul 10, 2026
158497a
fix(install): roll back rejected resolution staging
danielmeppiel Jul 10, 2026
6dd1a3f
fix: reject invalid manifest and policy schema values
danielmeppiel Jul 10, 2026
5c89f3e
fix: reconcile contracted deployment targets
danielmeppiel Jul 10, 2026
1d198a1
test(target): assert catalog-derived target discoverability incl. int…
danielmeppiel Jul 11, 2026
7b44b41
fix(deps): keep display paths tolerant of incomplete manifest identity
danielmeppiel Jul 11, 2026
599dc85
ci: document spec waiver for reliability fix
danielmeppiel Jul 11, 2026
d956781
ci: document spec waiver for reliability fix
danielmeppiel Jul 11, 2026
7e0c5d7
ci: document spec waiver for schema-validation fix
danielmeppiel Jul 11, 2026
43846be
fix: normalize resolution staging base path
danielmeppiel Jul 11, 2026
2403c13
Fix unknown target catalog guidance
danielmeppiel Jul 11, 2026
5d043ce
fix: preserve deployed state after target parse errors
danielmeppiel Jul 11, 2026
8d5de34
fix(policy): sanitize cached warnings
danielmeppiel Jul 11, 2026
e5d0d53
fix(uninstall): transfer shared deployed-path ownership
danielmeppiel Jul 11, 2026
c53e3fd
fix(install): preserve auth scheme in semver resolver
danielmeppiel Jul 11, 2026
937cd87
fix(mcp): purge managed servers from dropped targets
danielmeppiel Jul 11, 2026
5bb59ef
fix(install): trim resolve.py under LOC budget
danielmeppiel Jul 11, 2026
4942527
fix(install): only forward bearer scheme with a real token
danielmeppiel Jul 11, 2026
cc64daf
refactor(mcp): centralize current config source truth
danielmeppiel Jul 11, 2026
4a8edd1
merge(apm-rt-fix-2126): fold point fix into cure
danielmeppiel Jul 11, 2026
7c10149
merge(apm-rt-fix-2128): fold point fix into cure
danielmeppiel Jul 11, 2026
0179496
merge(apm-rt-fix-2130): fold point fix into cure
danielmeppiel Jul 11, 2026
d177b97
merge(apm-rt-fix-2129): fold point fix into cure
danielmeppiel Jul 11, 2026
8c7c1fb
merge(apm-rt-fix-2138): fold point fix into cure
danielmeppiel Jul 11, 2026
50e2b7c
merge(apm-rt-fix-2140): fold point fix into cure
danielmeppiel Jul 11, 2026
9551112
merge(apm-rt-fix-2137): fold point fix into cure
danielmeppiel Jul 11, 2026
3b5500d
merge(apm-rt-fix-2139): fold point fix into cure
danielmeppiel Jul 11, 2026
f9cb760
merge(apm-rt-fix-2148): fold point fix into cure
danielmeppiel Jul 11, 2026
bc2e35c
merge(apm-rt-fix-2150): fold point fix into cure
danielmeppiel Jul 11, 2026
7b2acb2
merge(apm-rt-fix-2149): fold point fix into cure
danielmeppiel Jul 11, 2026
5901205
test(install): mirror canonical managed_deploy_root in make_target mock
danielmeppiel Jul 11, 2026
86cf246
refactor(deploy): add canonical deployment ledger
danielmeppiel Jul 11, 2026
ea7f6ef
refactor(deploy): extract canonical reconciliation wrapper
danielmeppiel Jul 11, 2026
a67ae74
refactor(install): centralize legacy deployment writes
danielmeppiel Jul 11, 2026
1eb2b6c
refactor(uninstall): reconcile survivor ownership
danielmeppiel Jul 11, 2026
36c5e56
refactor(mcp): centralize runtime ownership writes
danielmeppiel Jul 11, 2026
97b3c0e
refactor(audit): enforce deployment owner invariant
danielmeppiel Jul 11, 2026
0d49d94
refactor(install): extend structured completion result
danielmeppiel Jul 11, 2026
a9aeb61
refactor(install): add canonical transaction owner
danielmeppiel Jul 11, 2026
f74a005
refactor(install): route completion through transaction
danielmeppiel Jul 11, 2026
6d3e04e
test(install): enforce exit-code ownership
danielmeppiel Jul 11, 2026
e75513e
test(targets): characterize capability metadata
danielmeppiel Jul 11, 2026
a51d4a7
feat(targets): add canonical capability catalog
danielmeppiel Jul 11, 2026
a1e7668
refactor(targets): derive detection projections
danielmeppiel Jul 11, 2026
8be2704
refactor(targets): bind native profiles to catalog
danielmeppiel Jul 11, 2026
74aba89
refactor(targets): route command surfaces through catalog
danielmeppiel Jul 11, 2026
07b600b
refactor(hooks): extract native-format converters to own module
danielmeppiel Jul 11, 2026
6fb9ee5
docs(changelog): merge duplicate Unreleased Fixed block
danielmeppiel Jul 11, 2026
ddd8563
fix(deploy): enforce canonical ownership invariants
danielmeppiel Jul 11, 2026
6433b2a
fix: make compile target capabilities truthful
danielmeppiel Jul 11, 2026
0fbf31a
fix(install): finalize transaction before summary
danielmeppiel Jul 11, 2026
cb0964e
docs(changelog): note compile-target and install-completion hardening
danielmeppiel Jul 11, 2026
3529272
fix: restore compile and install lifecycle contracts
danielmeppiel Jul 11, 2026
d0eb05b
fix: fold lifecycle architecture follow-ups
danielmeppiel Jul 11, 2026
8bcc6fd
refactor: centralize capability authorities
danielmeppiel Jul 11, 2026
7696064
refactor: enforce validate-before-mutate writes
danielmeppiel Jul 11, 2026
bec2023
refactor: centralize install and policy outcomes
danielmeppiel Jul 11, 2026
e1b6228
refactor: preserve dependency and registry intent
danielmeppiel Jul 11, 2026
95003c3
refactor: centralize process output and auth IO
danielmeppiel Jul 11, 2026
57c65f1
refactor: negotiate portable hook and manifest contracts
danielmeppiel Jul 11, 2026
30a7b52
fix: enforce runtime deadlines and registry locking
danielmeppiel Jul 11, 2026
717a2f4
fix: fold architectural review findings
danielmeppiel Jul 11, 2026
7920aac
refactor: keep dependency model within size guard
danielmeppiel Jul 11, 2026
db5a7b7
fix: close adjacent architecture reliability gaps
danielmeppiel Jul 11, 2026
13dcce0
fix: keep regenerated lockfiles machine-independent
danielmeppiel Jul 11, 2026
86b9546
fix: close bounded lifecycle review defects
danielmeppiel Jul 11, 2026
9b3319c
refactor: centralize deployment and ref winners
danielmeppiel Jul 12, 2026
3e7a415
test: correct bespoke GitLab token contract
danielmeppiel Jul 12, 2026
26425f2
test: align GitLab host credential scope
danielmeppiel Jul 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .agents/skills/python-architecture/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ description: >
- Follow existing patterns (BaseIntegrator, CommandLogger, AuthResolver) before inventing new ones
- Prefer composition over deep inheritance
- Push shared logic into base classes, not duplicated across siblings
- One canonical owner per decision: route through the existing authority (target_catalog, AuthResolver/host_providers, runtime registry, CommandLogger, CompiledOutputWriter, deployment_ledger, install-outcome, neutral hook IR, BaseIntegrator); extend it, never fork it. Full rule: `.apm/instructions/architecture.instructions.md`
- Lock every centralization with a dual guardrail: a regression test plus a static check in `scripts/lint-architecture-boundaries.sh`
5 changes: 5 additions & 0 deletions .apm/agents/apm-primitives-architect.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ Cite the principle by name in every recommendation. Never appeal to
trigger -- too noisy.
- New YAML manifests, new tools, or new dispatcher sub-agents when
wording changes would suffice.
- One capability split across two primitives (two skills, or a skill
and an agent, owning the same decision) -- duplication equals drift.
Give each capability one owning primitive; the same single-canonical
-owner rule that governs the Python codebase (see
architecture.instructions.md) governs primitive design.

## Scope boundaries

Expand Down
23 changes: 23 additions & 0 deletions .apm/agents/python-architect.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,29 @@ You are an expert Python architect specializing in CLI tool design. You guide ar
- **Collect-then-render**: `DiagnosticCollector` — push diagnostics during operation, render summary at end
- **BaseIntegrator**: All file integrators share one base for collision detection, manifest sync, path security

## Canonical authority discipline (single-owner rule)

Most APM reliability bugs reduce to one root: the same decision
(accepted targets, install outcome, hook shape, integrity hash,
resolved credential) was computed in more than one place, so a fix on
one path missed a sibling. Hold the line structurally:

- Every durable decision / vocabulary / outcome / write / contract has
exactly ONE canonical owner; every call site routes through it.
Extend the owner, never fork it. The enumerated owners and the full
rule live in `.apm/instructions/architecture.instructions.md`
(deployed to `.github/instructions/`) -- treat that file as the
canonical statement; do not restate it here.
- When you centralize a decision or fix a split-authority bug, ship a
DUAL guardrail: a behavioral regression test AND a static boundary
check (`scripts/lint-architecture-boundaries.sh` +
`tests/integration/test_architecture_*.py`). A fix without the guard
will silently regress.

At PR-review time, add one check to your findings: does the diff
compute or enforce a decision the codebase already owns elsewhere? A
new parallel authority is a `required` finding, not a nit.

## When to Abstract vs Inline

- **Abstract** when 3+ call sites share the same logic pattern
Expand Down
66 changes: 66 additions & 0 deletions .apm/instructions/architecture.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
applyTo: "src/apm_cli/**"
description: "Single canonical owner discipline: one authority per durable decision, guarded by a regression test + a static boundary check"
---

# Architecture discipline: one canonical owner per decision

APM is a pipeline of durable facts (targets, lock state, install
outcomes, compiled output, hook shapes, credentials, deployment
provenance). Most reliability bugs in this codebase have one shape:
the SAME decision was computed or enforced in more than one place, so
a fix on one path silently missed a sibling path. The cure is
structural, not case-by-case.

## The rule

Every durable decision, vocabulary, outcome, write, or contract has
exactly ONE canonical owner. Every call site routes THROUGH that owner
instead of re-deriving the answer locally.

- A "decision" is anything a reader must be able to trust is computed
identically everywhere: the accepted target set, whether an install
succeeded, the on-disk shape of a hook, the integrity hash of a
deployed file, the resolved credential for a host.
- Adding a second place that computes or enforces the same decision is
a "split authority" and is a defect even if it currently agrees --
it WILL drift the next time one side is patched.

## Existing canonical owners -- route through these, do not re-derive

| Decision / fact | Canonical owner |
|---|---|
| Accepted target vocabulary | core/target_catalog.py |
| Host + credential resolution | core/auth.py (AuthResolver), core/host_providers.py |
| Runtime descriptors | runtime/registry.py |
| User-facing output / diagnostics | CommandLogger / console owner |
| Compiled-output writes (atomic) | CompiledOutputWriter |
| Deployment provenance / state | deployment_ledger.py |
| Install success / failure outcome | the canonical install-outcome path |
| Neutral hook shape -> per-target native | the neutral hook IR + per-target integrators |
| File-level deploy / sync / cleanup | BaseIntegrator (see integrators.instructions.md) |

If you are about to compute one of these locally, stop and call the
owner. If the owner is missing a case you need, EXTEND the owner --
never fork it.

## When you centralize or fix a split-authority bug: dual guardrail

A fix is not done until the split cannot silently return. Add BOTH:

1. A behavioral **regression test** (hermetic, under tests/) that
encodes the exact symptom and fails before / passes after.
2. A **static boundary guard** so a future contributor cannot re-add a
second owner: extend scripts/lint-architecture-boundaries.sh and the
matching tests/integration/test_architecture_*.py suite.

The scripts/lint-architecture-boundaries.sh check is wired into CI (the
Lint job) alongside the auth-signal guard. Treat a new authority the
same way: give it a guard line.

## Review lens

When reviewing or authoring a change, ask: "Does this compute or
enforce a decision the codebase already owns elsewhere?" If yes, the
change must route through the owner, and a new parallel path is a
blocking finding, not a nit.
2 changes: 1 addition & 1 deletion .apm/instructions/integrators.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ APM runs inside repositories of any size — from single-package repos to monore
1. **One base, many file types.** All file-level integrators share a single `BaseIntegrator` infrastructure for collision detection, manifest-based sync, path security, link resolution, and file discovery. New integrators add *what* to deploy, never *how* to deploy. When logic belongs to more than one integrator, push it into `BaseIntegrator`.
2. **Pay only for what you touch.** Operations must be proportional to the files a single package deploys, not the size of the workspace or the total managed-files set. Pre-normalize once, partition once, look up in O(1). Avoid full-tree walks, per-file parent cleanup, or repeated set scans.

When evolving integration logic new file types, richer transforms, cross-package awareness preserve these properties. If a change would violate either principle, refactor the base class first.
When evolving integration logic -- new file types, richer transforms, cross-package awareness -- preserve these properties. If a change would violate either principle, refactor the base class first. This subsystem is the integration-specific instance of the repo-wide single-canonical-owner rule; see architecture.instructions.md.

## Required structure

Expand Down
2 changes: 2 additions & 0 deletions .apm/instructions/python.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ applyTo: '**/*.py'
Use type hints for all function parameters and return values.
Follow PEP 8 style guidelines.
Write comprehensive docstrings.

Before computing a shared decision (accepted targets, install outcome, hook shape, integrity hash, resolved credential) locally, route through its canonical owner instead of duplicating it; see architecture.instructions.md.
2 changes: 2 additions & 0 deletions .apm/skills/python-architecture/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ description: >
- Follow existing patterns (BaseIntegrator, CommandLogger, AuthResolver) before inventing new ones
- Prefer composition over deep inheritance
- Push shared logic into base classes, not duplicated across siblings
- One canonical owner per decision: route through the existing authority (target_catalog, AuthResolver/host_providers, runtime registry, CommandLogger, CompiledOutputWriter, deployment_ledger, install-outcome, neutral hook IR, BaseIntegrator); extend it, never fork it. Full rule: `.apm/instructions/architecture.instructions.md`
- Lock every centralization with a dual guardrail: a regression test plus a static check in `scripts/lint-architecture-boundaries.sh`
5 changes: 5 additions & 0 deletions .github/agents/apm-primitives-architect.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ Cite the principle by name in every recommendation. Never appeal to
trigger -- too noisy.
- New YAML manifests, new tools, or new dispatcher sub-agents when
wording changes would suffice.
- One capability split across two primitives (two skills, or a skill
and an agent, owning the same decision) -- duplication equals drift.
Give each capability one owning primitive; the same single-canonical
-owner rule that governs the Python codebase (see
architecture.instructions.md) governs primitive design.

## Scope boundaries

Expand Down
23 changes: 23 additions & 0 deletions .github/agents/python-architect.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,29 @@ You are an expert Python architect specializing in CLI tool design. You guide ar
- **Collect-then-render**: `DiagnosticCollector` — push diagnostics during operation, render summary at end
- **BaseIntegrator**: All file integrators share one base for collision detection, manifest sync, path security

## Canonical authority discipline (single-owner rule)

Most APM reliability bugs reduce to one root: the same decision
(accepted targets, install outcome, hook shape, integrity hash,
resolved credential) was computed in more than one place, so a fix on
one path missed a sibling. Hold the line structurally:

- Every durable decision / vocabulary / outcome / write / contract has
exactly ONE canonical owner; every call site routes through it.
Extend the owner, never fork it. The enumerated owners and the full
rule live in `.apm/instructions/architecture.instructions.md`
(deployed to `.github/instructions/`) -- treat that file as the
canonical statement; do not restate it here.
- When you centralize a decision or fix a split-authority bug, ship a
DUAL guardrail: a behavioral regression test AND a static boundary
check (`scripts/lint-architecture-boundaries.sh` +
`tests/integration/test_architecture_*.py`). A fix without the guard
will silently regress.

At PR-review time, add one check to your findings: does the diff
compute or enforce a decision the codebase already owns elsewhere? A
new parallel authority is a `required` finding, not a nit.

## When to Abstract vs Inline

- **Abstract** when 3+ call sites share the same logic pattern
Expand Down
66 changes: 66 additions & 0 deletions .github/instructions/architecture.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
applyTo: "src/apm_cli/**"
description: "Single canonical owner discipline: one authority per durable decision, guarded by a regression test + a static boundary check"
---

# Architecture discipline: one canonical owner per decision

APM is a pipeline of durable facts (targets, lock state, install
outcomes, compiled output, hook shapes, credentials, deployment
provenance). Most reliability bugs in this codebase have one shape:
the SAME decision was computed or enforced in more than one place, so
a fix on one path silently missed a sibling path. The cure is
structural, not case-by-case.

## The rule

Every durable decision, vocabulary, outcome, write, or contract has
exactly ONE canonical owner. Every call site routes THROUGH that owner
instead of re-deriving the answer locally.

- A "decision" is anything a reader must be able to trust is computed
identically everywhere: the accepted target set, whether an install
succeeded, the on-disk shape of a hook, the integrity hash of a
deployed file, the resolved credential for a host.
- Adding a second place that computes or enforces the same decision is
a "split authority" and is a defect even if it currently agrees --
it WILL drift the next time one side is patched.

## Existing canonical owners -- route through these, do not re-derive

| Decision / fact | Canonical owner |
|---|---|
| Accepted target vocabulary | core/target_catalog.py |
| Host + credential resolution | core/auth.py (AuthResolver), core/host_providers.py |
| Runtime descriptors | runtime/registry.py |
| User-facing output / diagnostics | CommandLogger / console owner |
| Compiled-output writes (atomic) | CompiledOutputWriter |
| Deployment provenance / state | deployment_ledger.py |
| Install success / failure outcome | the canonical install-outcome path |
| Neutral hook shape -> per-target native | the neutral hook IR + per-target integrators |
| File-level deploy / sync / cleanup | BaseIntegrator (see integrators.instructions.md) |

If you are about to compute one of these locally, stop and call the
owner. If the owner is missing a case you need, EXTEND the owner --
never fork it.

## When you centralize or fix a split-authority bug: dual guardrail

A fix is not done until the split cannot silently return. Add BOTH:

1. A behavioral **regression test** (hermetic, under tests/) that
encodes the exact symptom and fails before / passes after.
2. A **static boundary guard** so a future contributor cannot re-add a
second owner: extend scripts/lint-architecture-boundaries.sh and the
matching tests/integration/test_architecture_*.py suite.

The scripts/lint-architecture-boundaries.sh check is wired into CI (the
Lint job) alongside the auth-signal guard. Treat a new authority the
same way: give it a guard line.

## Review lens

When reviewing or authoring a change, ask: "Does this compute or
enforce a decision the codebase already owns elsewhere?" If yes, the
change must route through the owner, and a new parallel path is a
blocking finding, not a nit.
2 changes: 1 addition & 1 deletion .github/instructions/integrators.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ APM runs inside repositories of any size — from single-package repos to monore
1. **One base, many file types.** All file-level integrators share a single `BaseIntegrator` infrastructure for collision detection, manifest-based sync, path security, link resolution, and file discovery. New integrators add *what* to deploy, never *how* to deploy. When logic belongs to more than one integrator, push it into `BaseIntegrator`.
2. **Pay only for what you touch.** Operations must be proportional to the files a single package deploys, not the size of the workspace or the total managed-files set. Pre-normalize once, partition once, look up in O(1). Avoid full-tree walks, per-file parent cleanup, or repeated set scans.

When evolving integration logic new file types, richer transforms, cross-package awareness preserve these properties. If a change would violate either principle, refactor the base class first.
When evolving integration logic -- new file types, richer transforms, cross-package awareness -- preserve these properties. If a change would violate either principle, refactor the base class first. This subsystem is the integration-specific instance of the repo-wide single-canonical-owner rule; see architecture.instructions.md.

## Required structure

Expand Down
2 changes: 2 additions & 0 deletions .github/instructions/python.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ applyTo: '**/*.py'
Use type hints for all function parameters and return values.
Follow PEP 8 style guidelines.
Write comprehensive docstrings.

Before computing a shared decision (accepted targets, install outcome, hook shape, integrity hash, resolved credential) locally, route through its canonical owner instead of duplicating it; see architecture.instructions.md.
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ jobs:
- name: Lint - auth-protocol boundary (#1212 anti-regression)
run: bash scripts/lint-auth-signals.sh

- name: Lint - architecture authority boundaries
run: bash scripts/lint-architecture-boundaries.sh

# Linux-only for PR feedback. Full platform matrix (incl. macOS + Windows) runs post-merge in build-release.yml.
#
# Two-way sharded with pytest-split, mirroring the pattern proven in
Expand Down Expand Up @@ -308,4 +311,3 @@ jobs:
# .agents/skills/ content could silently diverge from source (#1716).
- name: apm audit --ci
run: uv run apm audit --ci

58 changes: 54 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,54 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]


### Changed

- Hardened command behavior: invalid lockfiles and incomplete policy chains
fail closed before mutation; failed installs skip post-install hooks;
registry routes do not fall back to Git; machine output keeps notices on
stderr; unauthenticated Git retries scrub inherited credentials; `$schema`
selects the manifest contract; and timed-out runtimes are reaped. (#2155)
- MCP audit, install, and uninstall now share one lockfile-bounded current-source
view, so `config-consistency` detects changed or removed transitive declarations
and fails on unreadable package manifests. (#2155)
- `apm compile --target <target>` now accepts every project target from the
canonical catalog, emits its native context artifact when applicable, and
treats targets without compile output as successful no-ops. (#2155)
- Merged hook configs now contain only each target's native upstream fields;
APM keeps reconciliation ownership in an external `apm-hooks.json` sidecar.
(#2155)

### Fixed

- Regenerating the lockfile now records each transitive local dependency's
identity as a project-root-relative POSIX path instead of an absolute machine
path, so a committed `apm.lock.yaml` stays portable and deterministic across
machines and CI. (#2155)
- Positional `apm install <url>` now exits non-zero when all packages fail
validation, matching manifest installs for reliable CI scripting. (#2131)
- A failed first `apm install` no longer leaves behind an `apm.yml` it created,
and the final completion summary now reflects the committed outcome instead of
rendering before commit or rollback. Successful dry-run bootstrap keeps the
generated manifest and explicit targets for the next run. (#2155)
- Manifest and policy parsers now reject wrong-typed native schema values and
report unknown policy keys. Migration: quote numeric `apm.yml` versions, use
non-empty string identities, and use mappings/lists for policy blocks. (closes #2137) (#2143)
- `apm uninstall` now transfers shared deployed-file ownership to a surviving
package, preserving lockfile content-integrity coverage. (#2148)
- Semver resolution now preserves each dependency's authentication scheme, so
Azure DevOps bearer credentials are used consistently for tag listing, and a
rejected `ADO_APM_PAT` retries ref resolution with the Azure CLI bearer. (#2155)
- Contracting the active target set now removes APM-managed MCP server
entries from dropped targets while preserving user-authored servers and
unrelated native config, including safe adoption of self-defined servers from
legacy lockfiles when the native entry exactly matches its stored baseline.
(#2155)
- `apm uninstall` now reconciles dependency removal, survivor ownership, hashes,
MCP state, and the deployment ledger before one atomic lockfile write. (#2155)
- `apm install` exception and rollback diagnostics now render through the
`CommandLogger` owner, keeping recovery hints and warning severity consistent.
(#2155)
- Fresh checkouts with declared consumer targets no longer remain
`apm audit --ci`-red for files those targets cannot restore: `apm install`
now removes stale `deployed_files` entries outside the legitimate target
Expand All @@ -18,12 +63,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `apm install --target intellij` now configures JetBrains Copilot MCP support
while routing package file primitives through the Copilot profile.
(by @sergio-sisternes-epam; closes #1957) (#2041)

### Fixed

- Global Claude installs now support an absolute `CLAUDE_CONFIG_DIR` outside
`HOME` without leaving a partial deployment. (closes #2129) (#2135)
- Azure DevOps marketplace checks now preserve suffix-free `/_git/<repo>` URLs
and pass Azure CLI bearer authentication through to `git ls-remote`. (closes #2119)

### Performance

- Deployment manifest reconciliation and uninstall ownership handoff now use
precomputed path indexes, avoiding quadratic scans on large deployment
ledgers. (#2155)

## [0.24.1] - 2026-07-10

### Fixed
Expand Down
Loading
Loading