# Changelog

All notable changes to this project will be documented in this file.

## [Unreleased]

### Added

- Setup command now resolves platform axes (issue adapter + code hosting)
  **before** skill injection, ensuring `inject_skills_with_summary` receives
  the detected/configured adapter and hosting values. Platform config is
  persisted via `save_platform_config` before injection runs when platform
  detection or override is active (including `--skip-platform-detection`
  combined with `--issue-adapter`). Pure `--skip-platform-detection` and
  `--system-only` bypass detection/persistence and use an inject-all or
  previously persisted resolved-axis path respectively, so an explicit/detected
  Jira adapter remains distinguishable from the default fallback.
- `--issue-adapter` override now also runs code hosting detection independently
  (previously it skipped all detection).
- Undetected hosting warning: when filtering is active but code hosting could
  not be determined, a `⚠` warning is emitted to stderr.
- Three-condition inject-all fallback: `--skip-platform-detection`, detection
  exception, or non-interactive (no TTY) → `(None, None)` axes forwarded to
  `inject_skills_with_summary` for full inject-all behavior.
- Non-interactive (no-TTY) detection now preserves an **authoritative**
  configured issue adapter — one where the raw config contains
  ``issue_adapter_resolved: true`` — instead of letting detection
  silently rewrite it to a detected platform (FR-002), mirroring the
  interactive and ``--system-only`` paths.  A legacy markerless
  ``issue_adapter: "jira"`` is treated as authoritative by
  ``detect_platforms`` (so Jira is still detected at medium confidence and
  preserved rather than replaced); only an explicit ``false`` marker — or a
  present-but-malformed (non-boolean, e.g. ``null`` / ``"false"``) marker —
  is non-authoritative.
- PyPI release command (`agdt-release-pypi`) with test gate,
  build/validate/upload flow, and summary output.
- `epic_tree.dependencies`: `UnresolvedRefError` (subclass of `KeyError`) with a
  structured `error_payload` dict for unresolved blocking refs; raised by
  `build_dependency_graph` instead of plain `KeyError`.
- `epic_tree.dependencies.detect_cycles` now returns `list[list[str]]` — one closed
  canonical cycle chain per cyclic SCC (e.g. `['a', 'b', 'c', 'a']`).
  Canonicalization **rotates** the chain to place the lexicographically smallest ref
  first while **preserving traversal direction** — every consecutive hop in the
  returned chain is a real edge in the directed graph. No reversed-chain comparison
  is performed.
- `epic_tree.dependencies.topological_sort` tiebreaker updated to
  `(order if order is not None else float('inf'), positional_index)` so nodes with
  an explicit `order` precede unordered nodes; `ValueError` on cycles now includes the
  concrete cycle chain.
