mcaxl/CHANGELOG.md
Ryan Malloy 0691ba8c46 2026.04.27.1: same-day post-release PII scrub
The original 2026.04.27 was published-then-deleted from PyPI within
hours after a stricter audit (against the unpacked sdist, not just
curated source paths) found cluster-fingerprint content that the
pre-publish grep had missed. This release supersedes the deleted one;
no functional differences.

Issues found in 2026.04.27 that this fixes:

1. docs/query-patterns/sip-trunk-report.md — "Live result snapshot"
   section (38 lines) contained the live cluster's actual SIP trunk
   inventory: real hostnames (exp-c-p.binghammemorial.org), real
   internal IPs (172.20.6.99, .104, .105, .114, .120, .222, plus
   172.20.2.22, 172.20.14.105, 172.24.10.10), real trunk-name +
   description rows. Section removed entirely. The query-pattern doc
   itself still ships — schema/SQL guidance is generic and useful.
   One inline FQDN example (`exp-c-p.binghammemorial.org`) replaced
   with `exp-c-p.example.com`. Status line that named the specific
   maintenance release (`Validated against CUCM 15.0.1.12900-234 on
   2026-04-25.`) genericized to `Validated against CUCM 15.`

2. .mcp.json shipping in sdist with `/home/rpm/bingham/axl` as the
   `--directory` argument. Local filesystem path = hostname leak.
   Added to `[tool.hatch.build.targets.sdist] exclude`. File stays
   in the source repo for development; no longer ships.

3. pyproject.toml comment about the audit workflow ironically
   contained the literal word "bingham" as the example grep token.
   Rewritten to use "site-specific tokens" generically.

Audit verification (against the unpacked sdist this time):
  tar -xzf dist/mcaxl-2026.4.27.1.tar.gz -C /tmp/sdist-inspect
  grep -rnEi 'bingham|binghammemorial|10\.[0-9]+\.[0-9]+\.[0-9]+|
              172\.(1[6-9]|2[0-9]|3[01])\.[0-9]+\.[0-9]+|
              192\.168\.[0-9]+\.[0-9]+|SupportedSystems|CCX-AXL|
              CER-AXL|CUC-AXL|TabSync|variphy|15\.0\.1\.12900|
              production cluster|/home/rpm|cucm-pub\.bingham'
       /tmp/sdist-inspect/
  → returns empty (verified)

Tests still 155/155.

Lesson encoded for next time: the pre-publish audit MUST run against
the unpacked sdist, not just the four explicitly-named paths in the
python.md rule (src/, tests/, README.md, pyproject.toml, .env.example).
The sdist also pulls in docs/, top-level dotfiles, and uv.lock.
CHANGELOG.md spells this out in the post-release note for next time.
2026-04-27 13:07:38 -06:00

98 lines
4.1 KiB
Markdown

# Changelog
This project uses [CalVer](https://calver.org/) — version numbers
encode the date the package was tested against the upstream Cisco APIs
and published. Format: `YYYY.MM.DD` with optional `.N` post-release
suffix for same-day fixes.
## 2026.04.27.1 — same-day PII scrub
Post-release fix per the python.md immutability rule. The original
`2026.04.27` was published-then-deleted from PyPI after a stricter
audit found cluster-fingerprint content in the shipped sdist that the
pre-publish audit had missed:
- `docs/query-patterns/sip-trunk-report.md` contained a "Live result
snapshot" section with the test cluster's actual SIP trunk inventory
(real hostnames, real internal IPs). The query-pattern doc itself
still ships; the snapshot section has been removed and one inline
FQDN example replaced with `.example.com`.
- `.mcp.json` was shipping in the sdist with a local filesystem path.
Added to `[tool.hatch.build.targets.sdist] exclude`. The file
remains in the source repo for development; it no longer ships.
Lesson encoded for next time: **the pre-publish PII audit must run
against the unpacked sdist, not just curated source paths.** The
sdist also pulls in `docs/`, top-level dotfiles like `.mcp.json`, and
`uv.lock`. The python.md rule's example grep covers fewer paths than
the actual sdist blast surface; the durable fix is `tar -xzf
dist/*.tar.gz -C /tmp/inspect && grep -rnE 'site-token' /tmp/inspect`
before every publish.
No functional changes between 2026.04.27 and 2026.04.27.1 — just
metadata and shipped-doc content.
## 2026.04.27 — initial public release (deleted)
> Yanked-and-deleted from PyPI on the publish date due to a sdist
> PII leak. Superseded by `2026.04.27.1`. Retained here as a marker.
First public release on PyPI as `mcaxl`. Renamed from the internal
working name `mcp-cucm-axl` to fit the operator's `mc<interface>`
naming convention.
### Tools (19 total)
**Foundational**: `axl_version`, `axl_sql`, `axl_list_tables`,
`axl_describe_table`, `cache_stats`, `cache_clear`, `health`.
**Route plan**: `route_partitions`, `route_calling_search_spaces`,
`route_patterns`, `route_inspect_pattern`, `route_lists_and_groups`,
`route_translation_chain`, `route_digit_discard_instructions`,
`route_device_pool_route_groups`, `route_devices_using_css`,
`route_filters`.
**Real-time registration (RisPort70)**: `device_registration_status`,
`device_registration_summary`.
### Prompts (10 total)
Schema-grounded conversation seeds: `route_plan_overview`,
`investigate_pattern`, `audit_routing`, `cucm_sql_help`,
`sip_trunk_report`, `phone_inventory_report`, `user_audit`,
`inbound_did_audit`, `hunt_pilot_audit`, `whoami`.
### Engineering rigor
- **Read-only by structural guarantee**: no AXL write methods are
registered; the SQL validator rejects non-SELECT/WITH queries as
defense-in-depth.
- **Hamilton-style review closed**: 7 findings (2 Critical, 3 Major,
2 Minor) addressed during pre-release hardening, each with a
regression test.
- **Live-cluster verified**: every tool path verified against a
live CUCM 15 cluster before release.
- **155 unit tests**, schema drift guard for all 71 known
`fkcallingsearchspace_*` columns (via
`test_complete_schema_coverage_against_known_columns`).
### Known limitations
- `route_translation_chain` evaluates CUCM wildcards (`X`, `!`,
`[0-9]`, `@`, `\\+`) but does not model route-filter constraints on
`@` patterns — use as guidance, not authoritative.
- AXL WSDL must be supplied externally (Cisco-licensed; not bundled).
See `README.md` for bootstrap instructions.
- RisPort `state_info` cursor pagination is implemented but not yet
stress-tested on clusters with > 1000 devices in a single class.
### Acknowledgments
Borrowed two ideas from
[`@calltelemetry/cisco-cucm-mcp`](https://github.com/calltelemetry/cisco-cucm-mcp)
(MIT licensed): the RisPort70 SOAP envelope shape and the
exponential-backoff retry policy on HTTP 503. Their tool covers
operational debugging (logs, perfmon, packet capture) — install both
side-by-side for compound questions like *"audit found CSS X
unreferenced AND RisPort confirms zero phones registered against it."*