one lifecycle hook that ends mount-order guessing
Amplifier builds every session from independent modules mounted in a fixed order. A module's mount() runs while the coordinator is only partially composed, so cross-module wiring never had a safe place to happen.
This is a real, shipped change — here's the proof.
Merged 2026-04-25 by Diego Colombo. The PR bumped the kernel from 1.3.3 to 1.4.0 and reached consumers via v1.4.1 — a change of +1598 / −25 across 24 files.
So why did a hook like this need to exist?
Because mount() sees only a partial coordinator, module authors checked for a capability in both mount() (not yet available) and in a request handler (too late to configure) — and stacked triple-path event discovery to survive the ordering they couldn't trust.
The fix is a single guaranteed moment after composition.
mount() and a request handlerIt runs after every module across every phase has finished mount(), in initialize_session — after the hooks loop and before session:fork. Every module gets one moment when the coordinator is fully composed.
And adopting it carries almost no risk.
Phase 6 walks the queue in mount registration order. A failing callback is caught and logged (WARNING, with exc_info) and emits a module:on_session_ready_failed event — while the remaining callbacks still run.
The contract behind it is enforced, not hoped for.
module:on_session_ready_failed with {module_id, error}check_on_session_ready() validates that the hook is async and takes a coordinator argument, wired into the hook, tool, orchestrator, provider and context validators — backed by 55 new/updated tests with 0 regressions.
Which is exactly what lets authors drop the old anti-pattern.
Every module now gets a fully-composed moment to wire its dependencies — which is exactly what lets it drop the defensive dual-path anti-pattern documented in CONTRACTS.md. Guessing mount order is replaced by a reliable post-composition hook.
The pattern generalizes beyond Amplifier: when independent parts compose in phases, one explicit "everything is ready now" moment retires the defensive, order-guessing init that fragile ordering otherwise forces.
Data as of: April 2026
Feature status: Shipped and released — merged to microsoft/amplifier-core main 2026-04-25 (PR #63); tags v1.4.0 and v1.4.1 exist; present in installed amplifier_core 1.6.0. Scope is Python-only.
Correct repository: microsoft/amplifier-core (the kernel). The initially-suggested michaeljabbour/amplifier-collab-core is a module, not the kernel, and returned 0 matches for on_session_ready.
Research performed:
gh pr list --repo microsoft/amplifier-core --state all --search on_session_ready --json number,title,mergedAt,authorgh pr view 63 --repo microsoft/amplifier-core --json additions,deletions,files,commits,body,mergedAt,authorgh pr view 68 --repo microsoft/amplifier-core --json bodysed -n '244,272p' amplifier_core/_session_init.py (installed v1.6.0)gh api repos/microsoft/amplifier-core/contents/crates/amplifier-core/src/events.rsgh api repos/microsoft/amplifier-core/contents/CONTRACTS.md | base64 -dgit remote -v; grep -n on_session_readyPrimary contributors: Diego Colombo (colombod) — author of PR #63 (feature + contract). Brian Krabach (bkrabach) — author of follow-up docs PR #68.
Gaps / excluded: Two speculative topic claims (a "7% observability graph" loss and Digital Twin Universe end-to-end verification) were independently re-checked, found unsupported, and deliberately omitted from this deck.