Skip to content

[docs] Update documentation for features from 2026-05-09#1219

Merged
danielmeppiel merged 1 commit into
mainfrom
docs/update-ado-auth-2026-05-09-46551a840a1682e8
May 9, 2026
Merged

[docs] Update documentation for features from 2026-05-09#1219
danielmeppiel merged 1 commit into
mainfrom
docs/update-ado-auth-2026-05-09-46551a840a1682e8

Conversation

@danielmeppiel
Copy link
Copy Markdown
Collaborator

Documentation Updates - 2026-05-09

This PR updates the documentation based on features merged in the last 24 hours.

Features Documented

Changes Made

  • Updated docs/src/content/docs/getting-started/authentication.md:
    • Clarified the stale-PAT fallback applies to apm install --update (not just plain apm install)
    • Added documentation for the new "AAD bearer fallback also failed" error message shown when both PAT and az bearer are rejected
    • Both paragraphs give users clear remediation guidance (refresh PAT or run az login)

Merged PRs Referenced

Notes

PRs #1215 and #1216 are internal consistency fixes that do not require new user-facing documentation. The agent-skills meta-target exclusion from error suggestions is consistent with what is already documented for apm targets. The outdated CLI help text fix is cosmetic and the command is already documented in cli-commands.md.

Note

🔒 Integrity filter blocked 1 item

The following item was blocked because it doesn't meet the GitHub integrity level.

  • #587 search_pull_requests: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".

To allow these resources, lower min-integrity in your GitHub frontmatter:

tools:
  github:
    min-integrity: approved  # merged | approved | unapproved | none

Generated by Daily Documentation Updater · ● 779.3K ·

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/daily-doc-updater.md@b87234850bf9664d198f28a02df0f937d0447295
  • expires on May 11, 2026, 5:42 AM UTC

…ostic

- Clarify that the stale-PAT->bearer fallback applies to 'apm install --update'
  preflight (previously undocumented; behavior fixed in #1214)
- Add the 'AAD bearer fallback also failed' diagnostic so users know both
  paths were attempted and understand which credential to refresh

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 9, 2026 05:42
@danielmeppiel danielmeppiel added automation Deprecated: use type/automation. Kept for issue history; will be removed in milestone 0.10.0. documentation Deprecated: use type/docs. Kept for issue history; will be removed in milestone 0.10.0. labels May 9, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the Azure DevOps authentication documentation to cover the PAT-to-az-bearer fallback behavior for apm install --update, and to describe the diagnostic users see when both credential paths fail.

Changes:

  • Document that ADO PAT rejection fallback also applies to apm install --update.
  • Add a section describing the message shown when both PAT and az-bearer authentication attempts fail.
Show a summary per file
File Description
docs/src/content/docs/getting-started/authentication.md Updates ADO auth fallback and failure diagnostics documentation for apm install --update.

Copilot's findings

Comments suppressed due to low confidence (1)

docs/src/content/docs/getting-started/authentication.md:197

  • The documented dual-fail diagnostic doesn’t match the current CLI output. I can’t find any code that emits "[x] AAD bearer fallback also failed for dev.azure.com."; instead AuthResolver.build_error_context(..., bearer_also_failed=True) prefixes the ADO Case 4 diagnostic with an indented line "ADO_APM_PAT was rejected; az cli bearer was also rejected." (no [x] prefix and different wording). Please update this section to reflect the actual emitted message/format so users can reliably recognize it.
If both `ADO_APM_PAT` and the `az` bearer fail, APM emits:

[x] AAD bearer fallback also failed for dev.azure.com.


This confirms both paths were attempted and neither succeeded, so the fix is either to refresh your PAT or run `az login`.
  • Files reviewed: 1/1 changed files
  • Comments generated: 1

Comment on lines +189 to +190
This fallback applies to all ADO operations including `apm install --update`. If you have a stale `ADO_APM_PAT` but an active `az login` session, `apm install --update` will succeed transparently via the bearer retry.

@danielmeppiel danielmeppiel merged commit 0ee3bc0 into main May 9, 2026
35 of 41 checks passed
@danielmeppiel danielmeppiel deleted the docs/update-ado-auth-2026-05-09-46551a840a1682e8 branch May 9, 2026 13:45
sergio-sisternes-epam pushed a commit that referenced this pull request May 9, 2026
…ostic (#1219)

- Clarify that the stale-PAT->bearer fallback applies to 'apm install --update'
  preflight (previously undocumented; behavior fixed in #1214)
- Add the 'AAD bearer fallback also failed' diagnostic so users know both
  paths were attempted and understand which credential to refresh

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel danielmeppiel mentioned this pull request May 10, 2026
danielmeppiel added a commit to slava-kudzinau/apm that referenced this pull request May 10, 2026
…crosoft#1189)

* fix: normalise flat-format dependencies for transitive resolution

Flat list dependencies (dependencies: [...]) were silently dropped
during parsing because from_apm_yml() only handled the dict form
(dependencies: {apm: [...]}).  The isinstance(..., dict) guard
caused the parser to skip flat lists entirely, leaving dependencies
as None and preventing transitive resolution.

Normalise flat lists to {apm: [...]} at parse time with a
DeprecationWarning guiding authors to the structured format.  Apply
the same fix for devDependencies.  Add defensive normalisation in
_apm_yml_writer.py to prevent AttributeError when reading raw YAML
with flat-format dependencies.

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

* refactor: reject flat-format dependencies with clear error instead of normalising

Replace the DeprecationWarning + silent normalisation with a hard
ValueError that tells authors exactly how to fix their apm.yml.

The flat list format was never documented or supported -- silently
accepting it is worse than failing loudly with actionable guidance.

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

* fix: reject all non-dict dependency types, not just lists

Address Copilot review feedback: the previous fix only rejected lists
but silently ignored strings, ints, and other scalars -- recreating
the original silent-drop failure mode. Now any non-dict value raises
ValueError with the actual type name.

Also hardens _apm_yml_writer.py to handle dependencies: null and
other scalar types.

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

* fix: target-agnostic local-bundle install (microsoft#1207) (microsoft#1217)

* fix: target-agnostic local-bundle install (microsoft#1207)

apm pack no longer hardcodes pack.target: copilot. Bundles now ship in
the Anthropic plugin layout as a transport convention only -- the
consumer target is resolved by apm install from project context and
primitives are routed per the resolved target's layout.

Defects fixed (per microsoft#1207 RCA):

- D1: pack records pack.target = "all" by default (or the auto-detected
  target). The flag remains for back-compat but is no longer the
  authoritative binding.
- D2.a: plugin.json is skipped on install regardless of casing in
  the bundle manifest. .mcp.json is also skipped from the verbatim
  deploy loop -- MCP wiring is surfaced as a follow-up notice.
- D2.b: instructions/*.md for compile-only targets (opencode, codex,
  gemini) are now staged under apm_modules/<slug>/.apm/instructions/
  so apm compile picks them up. Slug is validated through
  validate_path_segments and the destination is checked with
  ensure_path_within to block traversal escapes.
- D3: the local-bundle install path sets summary_rendered = True
  before returning so the outer finally-block no longer prints a
  misleading "Install interrupted" line on success.

check_target_mismatch returns None when the bundle records "all", so
target-agnostic bundles never warn against any consumer layout.

Tests:
- tests/unit/install/test_install_local_bundle_issue1207.py (13 cases)
- tests/integration/test_install_local_bundle_e2e.py
  TestInstallLocalBundleIssue1207: 7-row pack -> install matrix over
  copilot, claude, cursor, opencode, codex, gemini plus a multi-target
  consumer asserting both native and staged deployment paths.

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

* chore: stamp CHANGELOG with PR microsoft#1217

* Address panel review findings for microsoft#1207

- Case-insensitive .mcp.json skip in deploy loop and fallback walk
  (services.py) so case-folding filesystems cannot smuggle a renamed
  MCP file past the skip.
- Tighten staged_instructions disjunct in local_bundle_handler.py
  (drop dead first disjunct that always triggered for compile-only
  targets) and case-insensitive bundle_mcp detection.
- Compile hint now names the resolved target and primitive count.
- "Share with: apm install <bundle>" success line in apm pack output.
- Unit test class TestMcpJsonNeverDeployed covers case variants.
- e2e compile-hint assertion uses whitespace-collapsed output to
  survive logger line-wrap.
- Docs sweep:
  * pack-distribute.md: rewrote "Targeting mental model" as
    target-agnostic; removed --target examples; simplified cross-
    target -> plugin layout normalization.
  * cli-commands.md: marked apm pack --target deprecated; updated
    bundle install section; removed target-filter table.
  * lockfile-spec.md: pack.target is deprecated/optional informational
    metadata; bundle_files documented.
  * enterprise/security.md: added apm_modules/ allowed prefix with
    slug-validation note; new "Local bundle install trust model"
    subsection.
  * apm-usage skill (commands.md, workflow.md): pack.target is
    informational; OpenCode added to compile-needed list; new
    "Local bundle install" subsection.

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

* Iterate on panel review: harden slug validation + cleanup

Address apm-review-panel findings on PR microsoft#1217:

- sec-1: Enforce documented [A-Za-z0-9._-] slug whitelist in
  install/services.py before validate_path_segments, with explicit
  rejection of leading/trailing dots, '..', forward slashes, null bytes,
  and whitespace.  Aligns code with security.md trust model.

- sec-3: Add parameterized adversarial slug test cases
  (forward slash, null byte, leading/trailing dot, '@', whitespace).

- py-arch-2: Hoist plugin.json / .mcp.json case-insensitive metadata
  skip above the per-target deploy loop so multi-target installs do
  not inflate the skipped counter once per target.

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

* Address PR microsoft#1217 review: ASCII slug, MCP wiring, doc audit

- ASCII-only slug whitelist
- Preserve nested instruction subdirs in stage_root
- Pack success line mentions embedded apm.lock.yaml
- Strengthened plugin.json leak assertion (whole-tree walk)
- URL trailing-dot fix in security/marketplace error messages
- Auto-wire bundle .mcp.json through MCPIntegrator (multi-target)
  so non-Claude harnesses get servers in their native MCP config
- New TestBundleMcpWiring unit suite (parse + wire helpers)
- Doc audit: pack-distribute, lockfile-spec, plugins,
  cli-commands, first-package, security, CHANGELOG

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

* tests: add e2e coverage for bundle .mcp.json -> MCPIntegrator boundary

Four e2e cases covering the wiring path that was previously only
covered at the unit level:
- bundle .mcp.json reaches MCPIntegrator.install with the bundle's
  servers and the resolved-target CSV passed via explicit_target
- bundle without .mcp.json does not invoke the integrator (no
  spurious 'No MCP dependencies found' warnings on every install)
- integrator failure does not break the install (file deploys are
  not undone by an MCP wiring hiccup)
- dry-run never fires the integrator (zero side effects on the
  consumer's MCP config)

Per-target file writes (Claude project .mcp.json, .vscode/mcp.json,
.cursor/mcp.json) are owned by MCPIntegrator's own suite; testing
them here would require installed runtime binaries on the CI host.

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

* docs: fix broken anchor #authoring-workflow -> #plugin-authoring

Deploy Docs CI fails link validation; the actual heading is
'Plugin authoring' at the top of guides/plugins.md.

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

---------

Co-authored-by: Daniel Meppiel <copilot-rework@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Daniel Meppiel <[email protected]>

* docs(auth): document ADO --update bearer fallback and dual-fail diagnostic (microsoft#1219)

- Clarify that the stale-PAT->bearer fallback applies to 'apm install --update'
  preflight (previously undocumented; behavior fixed in microsoft#1214)
- Add the 'AAD bearer fallback also failed' diagnostic so users know both
  paths were attempted and understand which credential to refresh

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

* fix: surface malformed transitive manifests and add integration tests

Address reviewer feedback:

- Resolver catch site in _try_load_dependency_package now only catches
  FileNotFoundError (expected for missing manifests); ValueError
  propagates to the BFS result loop where it is logged at WARNING
  level, making malformed transitive deps user-visible.
- build_dependency_tree root-parse catch site now logs a warning
  instead of silently returning an empty tree.
- Writer error message includes structured-format hint matching the
  model-layer quality.
- Integration test (CliRunner): flat-list and string deps both exit
  non-zero with actionable error including 'expected a mapping' and
  structured-format example.
- Resolver test: transitive dep with flat-list deps surfaces WARNING
  and resolution continues for valid siblings.
- CHANGELOG entry under [Unreleased] Fixed.

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

---------

Co-authored-by: Sergio Sisternes <sergio.sisternes@epam.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Daniel Meppiel <51440732+danielmeppiel@users.noreply.github.com>
Co-authored-by: Daniel Meppiel <copilot-rework@github.com>
sergio-sisternes-epam pushed a commit that referenced this pull request May 19, 2026
…ostic (#1219)

- Clarify that the stale-PAT->bearer fallback applies to 'apm install --update'
  preflight (previously undocumented; behavior fixed in #1214)
- Add the 'AAD bearer fallback also failed' diagnostic so users know both
  paths were attempted and understand which credential to refresh

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sergio-sisternes-epam added a commit that referenced this pull request May 19, 2026
)

* fix: normalise flat-format dependencies for transitive resolution

Flat list dependencies (dependencies: [...]) were silently dropped
during parsing because from_apm_yml() only handled the dict form
(dependencies: {apm: [...]}).  The isinstance(..., dict) guard
caused the parser to skip flat lists entirely, leaving dependencies
as None and preventing transitive resolution.

Normalise flat lists to {apm: [...]} at parse time with a
DeprecationWarning guiding authors to the structured format.  Apply
the same fix for devDependencies.  Add defensive normalisation in
_apm_yml_writer.py to prevent AttributeError when reading raw YAML
with flat-format dependencies.

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

* refactor: reject flat-format dependencies with clear error instead of normalising

Replace the DeprecationWarning + silent normalisation with a hard
ValueError that tells authors exactly how to fix their apm.yml.

The flat list format was never documented or supported -- silently
accepting it is worse than failing loudly with actionable guidance.

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

* fix: reject all non-dict dependency types, not just lists

Address Copilot review feedback: the previous fix only rejected lists
but silently ignored strings, ints, and other scalars -- recreating
the original silent-drop failure mode. Now any non-dict value raises
ValueError with the actual type name.

Also hardens _apm_yml_writer.py to handle dependencies: null and
other scalar types.

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

* fix: target-agnostic local-bundle install (#1207) (#1217)

* fix: target-agnostic local-bundle install (#1207)

apm pack no longer hardcodes pack.target: copilot. Bundles now ship in
the Anthropic plugin layout as a transport convention only -- the
consumer target is resolved by apm install from project context and
primitives are routed per the resolved target's layout.

Defects fixed (per #1207 RCA):

- D1: pack records pack.target = "all" by default (or the auto-detected
  target). The flag remains for back-compat but is no longer the
  authoritative binding.
- D2.a: plugin.json is skipped on install regardless of casing in
  the bundle manifest. .mcp.json is also skipped from the verbatim
  deploy loop -- MCP wiring is surfaced as a follow-up notice.
- D2.b: instructions/*.md for compile-only targets (opencode, codex,
  gemini) are now staged under apm_modules/<slug>/.apm/instructions/
  so apm compile picks them up. Slug is validated through
  validate_path_segments and the destination is checked with
  ensure_path_within to block traversal escapes.
- D3: the local-bundle install path sets summary_rendered = True
  before returning so the outer finally-block no longer prints a
  misleading "Install interrupted" line on success.

check_target_mismatch returns None when the bundle records "all", so
target-agnostic bundles never warn against any consumer layout.

Tests:
- tests/unit/install/test_install_local_bundle_issue1207.py (13 cases)
- tests/integration/test_install_local_bundle_e2e.py
  TestInstallLocalBundleIssue1207: 7-row pack -> install matrix over
  copilot, claude, cursor, opencode, codex, gemini plus a multi-target
  consumer asserting both native and staged deployment paths.

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

* chore: stamp CHANGELOG with PR #1217

* Address panel review findings for #1207

- Case-insensitive .mcp.json skip in deploy loop and fallback walk
  (services.py) so case-folding filesystems cannot smuggle a renamed
  MCP file past the skip.
- Tighten staged_instructions disjunct in local_bundle_handler.py
  (drop dead first disjunct that always triggered for compile-only
  targets) and case-insensitive bundle_mcp detection.
- Compile hint now names the resolved target and primitive count.
- "Share with: apm install <bundle>" success line in apm pack output.
- Unit test class TestMcpJsonNeverDeployed covers case variants.
- e2e compile-hint assertion uses whitespace-collapsed output to
  survive logger line-wrap.
- Docs sweep:
  * pack-distribute.md: rewrote "Targeting mental model" as
    target-agnostic; removed --target examples; simplified cross-
    target -> plugin layout normalization.
  * cli-commands.md: marked apm pack --target deprecated; updated
    bundle install section; removed target-filter table.
  * lockfile-spec.md: pack.target is deprecated/optional informational
    metadata; bundle_files documented.
  * enterprise/security.md: added apm_modules/ allowed prefix with
    slug-validation note; new "Local bundle install trust model"
    subsection.
  * apm-usage skill (commands.md, workflow.md): pack.target is
    informational; OpenCode added to compile-needed list; new
    "Local bundle install" subsection.

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

* Iterate on panel review: harden slug validation + cleanup

Address apm-review-panel findings on PR #1217:

- sec-1: Enforce documented [A-Za-z0-9._-] slug whitelist in
  install/services.py before validate_path_segments, with explicit
  rejection of leading/trailing dots, '..', forward slashes, null bytes,
  and whitespace.  Aligns code with security.md trust model.

- sec-3: Add parameterized adversarial slug test cases
  (forward slash, null byte, leading/trailing dot, '@', whitespace).

- py-arch-2: Hoist plugin.json / .mcp.json case-insensitive metadata
  skip above the per-target deploy loop so multi-target installs do
  not inflate the skipped counter once per target.

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

* Address PR #1217 review: ASCII slug, MCP wiring, doc audit

- ASCII-only slug whitelist
- Preserve nested instruction subdirs in stage_root
- Pack success line mentions embedded apm.lock.yaml
- Strengthened plugin.json leak assertion (whole-tree walk)
- URL trailing-dot fix in security/marketplace error messages
- Auto-wire bundle .mcp.json through MCPIntegrator (multi-target)
  so non-Claude harnesses get servers in their native MCP config
- New TestBundleMcpWiring unit suite (parse + wire helpers)
- Doc audit: pack-distribute, lockfile-spec, plugins,
  cli-commands, first-package, security, CHANGELOG

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

* tests: add e2e coverage for bundle .mcp.json -> MCPIntegrator boundary

Four e2e cases covering the wiring path that was previously only
covered at the unit level:
- bundle .mcp.json reaches MCPIntegrator.install with the bundle's
  servers and the resolved-target CSV passed via explicit_target
- bundle without .mcp.json does not invoke the integrator (no
  spurious 'No MCP dependencies found' warnings on every install)
- integrator failure does not break the install (file deploys are
  not undone by an MCP wiring hiccup)
- dry-run never fires the integrator (zero side effects on the
  consumer's MCP config)

Per-target file writes (Claude project .mcp.json, .vscode/mcp.json,
.cursor/mcp.json) are owned by MCPIntegrator's own suite; testing
them here would require installed runtime binaries on the CI host.

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

* docs: fix broken anchor #authoring-workflow -> #plugin-authoring

Deploy Docs CI fails link validation; the actual heading is
'Plugin authoring' at the top of guides/plugins.md.

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

---------

Co-authored-by: Daniel Meppiel <copilot-rework@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Daniel Meppiel <[email protected]>

* docs(auth): document ADO --update bearer fallback and dual-fail diagnostic (#1219)

- Clarify that the stale-PAT->bearer fallback applies to 'apm install --update'
  preflight (previously undocumented; behavior fixed in #1214)
- Add the 'AAD bearer fallback also failed' diagnostic so users know both
  paths were attempted and understand which credential to refresh

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

* fix: surface malformed transitive manifests and add integration tests

Address reviewer feedback:

- Resolver catch site in _try_load_dependency_package now only catches
  FileNotFoundError (expected for missing manifests); ValueError
  propagates to the BFS result loop where it is logged at WARNING
  level, making malformed transitive deps user-visible.
- build_dependency_tree root-parse catch site now logs a warning
  instead of silently returning an empty tree.
- Writer error message includes structured-format hint matching the
  model-layer quality.
- Integration test (CliRunner): flat-list and string deps both exit
  non-zero with actionable error including 'expected a mapping' and
  structured-format example.
- Resolver test: transitive dep with flat-list deps surfaces WARNING
  and resolution continues for valid siblings.
- CHANGELOG entry under [Unreleased] Fixed.

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

---------

Co-authored-by: Sergio Sisternes <sergio.sisternes@epam.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Daniel Meppiel <51440732+danielmeppiel@users.noreply.github.com>
Co-authored-by: Daniel Meppiel <copilot-rework@github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automation Deprecated: use type/automation. Kept for issue history; will be removed in milestone 0.10.0. documentation Deprecated: use type/docs. Kept for issue history; will be removed in milestone 0.10.0.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants