You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bump pyproject.toml to 0.16.0 (and uv.lock). Move [Unreleased]
to [0.16.0] - 2026-05-28 in CHANGELOG.md with one concise 'so what'
entry per PR merged since v0.15.0.
Minor bump (not patch) is required: the cycle carries a BREAKING
change to apm install exit-code semantics plus new user-facing
features (apm deps why, semver ranges on git deps,
require_pinned_constraint policy, OpenAPM v0.1 spec).
Lint mirror green locally (ruff check + format, pylint R0801,
auth-signals).
Post-merge: tag v0.16.0 to trigger the release workflow.
Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+20-22Lines changed: 20 additions & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,36 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
8
8
## [Unreleased]
9
9
10
+
## [0.16.0] - 2026-05-28
11
+
10
12
### Added
11
13
12
-
- OpenAPM v0.1 normative specification at `docs/src/content/docs/specs/openapm-v0.1.md`, JSON Schemas for manifest/lockfile/policy, and conformance fixture seed tree under `tests/fixtures/spec-conformance/` (#1502).
13
-
- `batch-bug-shepherd` skill: refactored to a single shepherd-driver convergence loop that closes four production gaps surfaced by the in-flight bug-queue sweep. (1) Fold-by-default recommendation loop -- every panel CEO follow-up and Copilot inline review item is run through `assets/fold-vs-defer-rubric.md` and folded unless it crosses the PR's stated scope. (2) Copilot PR review address loop -- Phase X.0 fetches `copilot-pull-request-reviewer[bot]` review per `assets/copilot-classification-prompt.md`, classifies each item LEGIT/NOT-LEGIT (2-round cap), and folds LEGIT into the same iteration. (3) Post-push CI verification loop -- `gh pr checks --watch` after every push, with `assets/ci-recovery-checklist.md` bucketing failures (lint / test / infra / unknown) under a 3-iteration cap. (4) Orchestrator ownership signal -- assigns the shepherd actor and applies `status/shepherding` on pickup; the label is cleared on terminal state. New `assets/shepherd-driver-prompt.md` replaces the old shepherd-and-completion split. New step X.8 captures a per-PR mergeability snapshot via `gh pr view --json mergeable,mergeStateStatus,statusCheckRollup`; the snapshot lands in the PR advisory comment and is aggregated by the orchestrator into a saga-end mergeability status table (PR, head SHA, CEO stance, outer iterations, folds, deferrals, Copilot rounds, CI status, mergeable, mergeStateStatus, notes) defined in `assets/final-report-template.md` and constrained by the extended `assets/verdict-schema.json` completion-return shape. Validated on the wave-2 shepherd run that drove PRs #1472, #1512, #1513, #1514, #1515, #1516 to advisory-terminal -- PR #1514 hit 4 outer iterations with 11 folds + 1 deferral. (#1518)
14
-
-Deterministic Artifactory boundary probe: at install time, `_resolve_artifactory_boundary` HEAD-probes the candidate archive URLs and rebuilds the dependency reference at the proxy-verified split. Covers both explicit-FQDN (`host/artifactory/key/owner/repo/...`) and bare-shorthand-under-proxy deps. Distinguishes "missing repo" from auth (401/403) errors; uses `allow_redirects=False` so the bearer token can't leak cross-host. Mirrors the native GitLab probing pattern but without a separate metadata API. (#1472)
15
-
-`ref:` on git-source dependencies now accepts semver ranges (`^1.2.0`, `~1.4`, `>=2.0 <3`, `1.5.x`). `apm install` runs `git ls-remote`, picks the highest tag matching the range, and pins the resolved tag, commit SHA, version, and original constraint in `apm.lock.yaml`. Subsequent installs replay the lockfile without network; use `apm install --update` to re-resolve against current remote tags. Two tag patterns are tried in order (`v{version}`, `{name}--v{version}`) with a bare `{version}` fallback. (closes #1488)
16
-
-`apm deps why <package>` explains why a transitive dependency is installed by walking the lockfile's `resolved_by` chain back to the user's direct declaration in `apm.yml`. Supports `--global` for user-scope lockfiles and `--json` for scriptable output (JSON to stdout, all logs to stderr; analogue of `npm why` / `yarn why`). Exits `0` on success, `1` when the package isn't installed or the query is ambiguous, `2` when no lockfile exists. (#1490)
14
+
- OpenAPM v0.1 normative spec at `docs/src/content/docs/specs/openapm-v0.1.md` with JSON Schemas for manifest/lockfile/policy and conformance fixtures under `tests/fixtures/spec-conformance/`, so third-party integrators can build conformant tools without reading the rest of the APM docs. (closes #1502, #1517)
15
+
-`ref:` on git-source dependencies now accepts semver ranges (`^1.2.0`, `~1.4`, `>=2.0 <3`, `1.5.x`). `apm install` resolves the highest matching remote tag and pins the resolved tag, SHA, and constraint in `apm.lock.yaml`; subsequent installs replay offline, `apm install --update` re-resolves. (closes #1488, #1496)
16
+
-`apm deps why <package>` explains why a transitive dependency was installed by walking the lockfile back to your direct declaration in `apm.yml`. Supports `--global` and `--json`; analogue of `npm why` / `yarn why`. (#1495)
17
+
-`policy.dependencies.require_pinned_constraint: true` bans unbounded version ranges across `apm.yml`, blocking accidental drift in governed environments. (#1494)
18
+
-Deterministic Artifactory boundary probe at install time, so nested GitLab group/subgroup repos behind a JFrog proxy install correctly via the bare-shorthand form (previously failed with HTTP 404). Auth errors (401/403) are now distinguishable from missing-repo errors, and bearer tokens cannot leak cross-host via redirect. (#1472)
17
19
18
20
### Changed
19
21
20
-
-**BREAKING:**`apm install` now exits `1` whenever the diagnostic summary reports `Installation failed with N error(s)`. Previously the command exited `0` even after reporting errors, so CI could not detect failure via exit code. `--force` continues to bypass only the security scan's critical-finding block; it does **not** suppress general install errors (matches `npm` / `pip` / `cargo`). Callers that asserted `exit_code == 0` while errors were reported must update.
21
-
- Parse-time Artifactory boundary detection no longer uses directory-marker heuristics (`skills/`, `prompts/`, `agents/`, `collections/`, `instructions/`). The install-time resolver is authoritative for the (owner, repo, virtual_path) split. Parse-time defaults differ by mode:
22
-
-**Explicit FQDN** (`host/artifactory/key/owner/repo/...`): `parse_artifactory_path` stays intentionally shallow -- `owner` = first segment after the prefix, `repo` = next segment, remainder = `virtual_path`.
23
-
-**Bare shorthand under `PROXY_REGISTRY_ONLY`**: `_bare_shorthand_repo_segment_count` defaults to all-as-repo with a structural file-extension rule on the last segment (a path ending in `.prompt.md`/`.instructions.md`/`.chatmode.md`/`.agent.md` is by shape a virtual file; everything before it is the repo).
24
-
25
-
Both modes converge at install time: `_resolve_artifactory_boundary` HEAD-probes candidate splits and rebuilds the dependency reference at the proxy-verified split. The `_VIRTUAL_PATH_ROOT_SEGMENTS`, `_ARTIFACTORY_VIRTUAL_MARKERS`, and `_ARTIFACTORY_VIRTUAL_FILE_EXTENSIONS` constants are removed. (#1472)
22
+
-**BREAKING:**`apm install` now exits `1` whenever the diagnostic summary reports `Installation failed with N error(s)`. Previously it exited `0` even after reporting errors, so CI could not detect failure. `--force` continues to bypass only the security scan's critical-finding block; it does not suppress general install errors (matches `npm` / `pip` / `cargo`). Callers that asserted `exit_code == 0` while errors were reported must update. (#1496)
23
+
- Artifactory parse-time boundary detection no longer relies on directory-name heuristics (`skills/`, `prompts/`, `agents/`, `collections/`, `instructions/`); the install-time HEAD probe is now authoritative for the `(owner, repo, virtual_path)` split. Explicit FQDN refs use a shallow `owner/repo` split; bare shorthand under `PROXY_REGISTRY_ONLY` uses a structural file-extension rule. (#1472)
26
24
27
25
### Fixed
28
26
29
-
-`install.ps1` Windows installer now works on accounts whose profile directory contains non-ASCII characters (e.g. an accented username). Previously `apm --version` reported `The system cannot find the path specified.` because the generated `apm.cmd` shim baked in an ASCII-mangled path. The shim now embeds the literal `%LOCALAPPDATA%` token (cmd.exe expands at runtime) when the install root lives under the local profile, percent-escapes literal `%` characters in custom `APM_INSTALL_DIR` paths, and carries an advisory `REM` so hand-edits do not re-introduce the bug. The shim is written as ASCII (cmd.exe does not auto-detect UTF-16 .cmd files invoked through PATH, even with a BOM); the `%LOCALAPPDATA%` literal token keeps the embedded target ASCII-safe regardless of the user's profile path encoding. (closes #1509) (#1512)
30
-
-`apm install` against `target: opencode` now warns at install time when an agent's frontmatter has shapes OpenCode's Zod schema rejects (`tools:` as list/string instead of `name -> bool` mapping, or `color:` as a non-hex/non-theme value), so users learn why OpenCode refuses to load the agent instead of seeing only a runtime crash. The file is still copied verbatim; a per-target frontmatter transformer is tracked separately. (Phase 1 of #581, #1513)
31
-
-`apm compile --target claude` (and the `claude_md` target generally) now honors `compilation.strategy: single-file` and `--single-agents`, collapsing into a single root `CLAUDE.md` instead of silently emitting per-subdirectory `CLAUDE.md` files. Single-file compilation now behaves consistently across all supported targets. (closes #1445) (#1514)
32
-
-`apm install git@gitlab.com:owner/repo.git#ref` now succeeds for users with an SSH key and no `GITLAB_APM_PAT` / `GITLAB_TOKEN`. The validator previously ignored the explicit SSH transport on GitLab refs and demanded an HTTPS-token probe, which raised `Authentication failed for gitlab.com / No token available` even though the matching `dependencies.apm` entry in `apm.yml` installed cleanly via SSH. The validation path now mirrors the clone path (and the existing generic-host explicit-ssh arm) and honors `APM_ALLOW_PROTOCOL_FALLBACK=1` with SSH-first ordering. GitLab SSH-key users get the same frictionless install experience GitHub SSH users already had, matching `apm.yml` end-to-end. (closes #1501)
33
-
-`apm install -g` now correctly integrates hook JSON files authored in the "naked" Claude settings-slice format (event names at top-level, no outer `hooks:` wrap) into `.claude/settings.json`, `.cursor/hooks.json`, and the copilot per-event layout. Previously the file parsed cleanly but produced an empty merge while the user-facing summary still reported `1 hook(s) integrated`. The integrated-hook counter now only increments for files that actually contributed entries, malformed shapes where `hooks` is not a dict fail closed with a warning, and files that contribute zero entries log a warning instead of silently skipping. (closes #1499) (#1516)
34
-
- `apm install` against a registry proxy now works for GitLab nested-group repos (3+ path segments, e.g. `group/subgroup/project`). Previously the proxy resolver guessed `owner/repo` from the first two path segments and treated the rest as an in-repo virtual sub-path, so the downloader requested the wrong archive URL and the install failed with HTTP 404. The new install-time probe HEAD-walks candidate splits against the proxy and locks in the first one whose archive responds, so nested shorthand (`apm install <host>/artifactory/<key>/<group>/<subgroup>/<project>` or the bare-shorthand form under `PROXY_REGISTRY_URL` + `PROXY_REGISTRY_ONLY=1`) just works. The probe distinguishes auth (401/403) from missing-repo (4xx) so a misconfigured token surfaces as an auth problem instead of a "missing repo", and runs with `allow_redirects=False` so the bearer token cannot follow a redirect off the proxy host. When the proxy is unreachable, the `//` notation can mark the repo/virtual boundary explicitly as an escape hatch. (#1472)
35
-
-URL-form Artifactory deps no longer round-trip with the `artifactory/<key>` prefix folded into `repo_url`. The duplicated prefix caused the downloader to construct double-prefixed archive URLs (`/artifactory/key/artifactory/key/owner/repo/...`) and 404. `_validate_url_repo_path` now strips the Artifactory VCS prefix before returning the bare `owner/repo` slug; the prefix is still recovered separately via `_extract_artifactory_prefix`. (#1472)
36
-
-`apm install --update` now re-resolves direct git-source semver dependencies. Previously, when the dependency's install path already existed on disk, the BFS resolver short-circuited and `--update` was a silent no-op for git-semver refs; the lockfile kept the previously-resolved tag.
37
-
-`apm unpack` deprecation banner softened from "will be removed in v0.14" to "will be removed in a future release". The previous wording shipped past v0.14.0 and contradicted reality (the command still ships in v0.15.0). A concrete removal version will be re-stated once a removal milestone is set.
38
-
-`policy.dependencies.require_pinned_constraint: true` no longer misclassifies the npm- and cargo-style explicit-equality form `=1.2.3` as `BARE_BRANCH`. Both `1.2.3` and `=1.2.3` are now recognized as pinned constraints; the pip-style `==1.2.3` form is still rejected (not part of node-semver). Follow-up to #1494 / #1505.
39
-
-`apm uninstall` now fully cleans `.windsurf/skills/<pkg>/` directories on the `windsurf` target (by @yoelabril, #1486). The deploy path itself will move to `.agents/skills/` per Cascade's native cross-agent discovery -- tracked in #1520.
27
+
-`install.ps1`on Windows now works on accounts whose profile path contains non-ASCII characters (e.g. an accented username): the generated `apm.cmd` shim embeds the literal `%LOCALAPPDATA%` token instead of a baked, code-page-mangled path. Previously `apm --version` reported `The system cannot find the path specified.` (closes #1509, #1512)
28
+
-`apm.cmd` Windows shim is now written as ASCII so `cmd.exe` parses it correctly when invoked via `PATH`. A previous attempt to write the shim as UTF-16LE broke fresh installs with garbled output and exit code 1. (#1522)
29
+
-`install.ps1` is now strict ASCII, so `apm self-update` on `cp1252` Windows consoles no longer crashes with `UnicodeEncodeError: 'charmap' codec can't encode characters`. (#1523)
30
+
-`apm install --target opencode` now warns at install time when an agent's frontmatter has shapes OpenCode's Zod schema rejects (`tools:` as list/string, non-hex/non-theme `color:`), so users learn why OpenCode refuses the agent instead of hitting only a runtime crash. (Phase 1 of #581, #1513)
31
+
-`apm compile --target claude` now honors `compilation.strategy: single-file` and `--single-agents`, collapsing into one root `CLAUDE.md`instead of silently emitting per-subdirectory files. (closes #1445, #1514)
32
+
-`apm install git@gitlab.com:owner/repo.git#ref` now succeeds for users with an SSH key and no `GITLAB_APM_PAT` / `GITLAB_TOKEN`: the validator honors the explicit SSH transport instead of demanding an HTTPS-token probe. GitLab SSH-key users get parity with GitHub SSH users. (closes #1501, #1515)
33
+
-`apm install -g` now correctly integrates hook JSON files authored in the "naked" Claude settings-slice format (event names at top-level, no outer `hooks:` wrap). Previously the file parsed cleanly but merged nothing while the summary still reported `1 hook(s) integrated`; the counter now reflects actual contributions and malformed shapes fail closed with a warning. (closes #1499, #1516)
34
+
-`apm install --update` now re-resolves direct git-source semver dependencies even when the dependency's install path already exists; previously the BFS resolver short-circuited and `--update` was a silent no-op for git-semver refs. (#1496)
35
+
-`policy.dependencies.require_pinned_constraint: true` no longer misclassifies the npm/cargo explicit-equality form `=1.2.3` as `BARE_BRANCH`. Both `1.2.3` and `=1.2.3` are pinned; pip-style `==1.2.3` is still rejected. (follow-up to #1494, #1506)
36
+
-`apm uninstall` now fully cleans `.windsurf/skills/<pkg>/` directories on the `windsurf` target. (by @yoelabril, #1486)
37
+
-`apm unpack` deprecation banner softened from "will be removed in v0.14" to "will be removed in a future release"; the previous wording shipped past v0.14.0 and contradicted reality. (#1511)
0 commit comments