Messaging bounded context of the shopsystem product. Owns:
- Pydantic schemas for the inter-shop message types under the
importable package
catalog(AssignScenarios,RequestBugfix,RequestMaintenance,Clarify,WorkDone,MechanismObservation,Nudge, plus theScenarioPayloadand message-union helpers). shop-msgCLI, the tool that lead and BC shops use to read their inbox and write outbox replies on the inter-shop wire format.features/— the Gherkin scenarios that pin the messaging BC's behavior. Authored by the product (lead) shop; implemented and exercised here via pytest-bdd.
Speaks one ubiquitous language: message_type, work_id, schema, validation, inbox, outbox, send, respond, read, wire format. See ADR-001 for the BC-of-the-shopsystem framing that drove this packaging.
The authoritative catalogue is 05-inter-shop-protocol.md §5.3 (as
amended 2026-06-12); this list mirrors it for count and contents. The
catalogue enumerates eight implemented message types: the lead → BC
dispatch verbs plus the BC → lead responses, all carrying a shop-msg
subcommand and a catalog schema class.
Lead → BC dispatch verbs:
assign_scenarios— dispatch a feature's Gherkin scenarios to a BC.request_bugfix— dispatch a bug repair (may carry scenarios).request_maintenance— dispatch a non-behavioral chore (no scenarios).request_completion_journal— implemented (lead-f1ui). Symmetric completion-journal request, live as both ashop-msg sendand ashop-msg respondsubcommand, backed by theRequestCompletionJournal/RequestCompletionJournalResponseschema classes. The journal responder ships in shopsystem-scenarios (lead-8z3f).nudge— symmetric operational-liveness ping (ADR-015), flowing both lead → BC and BC → lead; carries a reason enum and noscenario_hashes.
BC → lead responses:
work_done— report a dispatch complete or blocked.clarify— ask a clarifying question on an ambiguous work item.mechanism_observation— surface a load-bearing, out-of-scope property of the mechanism itself.request_completion_journal— also surfaces as a BC → leadrespondsubcommand (see above); the verb is symmetric.
request_scenario_register and request_shop_card remain §5.3 named
reservations with no schema class and no shop-msg subcommand; they are
not part of the eight implemented types above.
Phase-1 distribution is via git URL (no PyPI yet — ADR-001 §Phase-1 wiring):
pip install "git+https://github.com/dstengle/shopsystem-messaging@v0.1.0"This pulls in shopsystem-scenarios
at tag v0.1.0 as a transitive dependency. The scenarios package owns
the canonical Gherkin-hashing rule that ScenarioPayload.hash is
validated against; messaging delegates to it rather than duplicating.
The console script is shop-msg. Subcommands are split into respond
(BC -> lead replies, written to <bc-root>/outbox/), send (lead ->
BC dispatches, written to <bc-root>/inbox/), and read (read the
latest outbox file for a work_id):
shop-msg --help
# BC responds to a lead-assigned work item, completed
shop-msg respond work_done \
--bc-root /path/to/bc --work-id lead-042 \
--status complete --summary "All three scenarios green"
# BC asks a clarifying question on an ambiguous work item
shop-msg respond clarify \
--bc-root /path/to/bc --work-id lead-042 \
--question "Does 'expired' include items past 24h?"
# Lead dispatches scenarios to a BC
shop-msg send assign_scenarios \
--bc-root /path/to/bc --work-id lead-043 \
--feature-title "Coupon redemption" --bc-tag billing \
--scenario-file scenarios/coupon-applied.featuresend assign_scenarios and send request_bugfix shell out to the
scenarios hash CLI from the scenarios package to compute each
scenario's canonical hash — the same rule the schema validator
enforces, reached from two directions (Python import on the schema
side, subprocess on the CLI side).
pip install -e ".[dev]"
pytest tests/ -vThe dev/CI bootstrap MUST install first-party packages editable
(pip install -e ".[dev]") — never a bare pip install ., which bakes a
frozen, non-editable copy of catalog/shop_msg into site-packages that
can shadow src/ and make pytest validate stale code (bd
shopsystem-messaging-c1f). A collection-time guard in tests/conftest.py
enforces this: if any first-party package resolves from a frozen
site-packages/dist-packages copy instead of an editable src/ checkout,
pytest collection fails fast — before any test runs — naming the offending
package and its resolved path. If you hit that guard, reinstall editable:
pip install -e ".[dev]".
Two pytest suites: catalog schema tests (tests/test_*.py) and BDD
features (tests/test_features.py discovers features/*.feature).
The integration test under tests/integration/ pins the cross-package
agreement with shopsystem-scenarios.
MIT. See LICENSE.