Conversation
`build_container` now takes a comma-separated list of `module:callable` selectors and applies them in order after the core defaults are bound, so two independent extensions (a budget-alerts plugin and a custom identity adapter, say) coexist without one wrapping the other. A later bind still wins; a blank entry, a trailing comma included, refuses to start naming its position, and a selector that cannot be loaded fails startup as before. The container summary names each selector with what it rebound and contributed, computed against a snapshot taken before that selector ran. Single-selector behavior and messages are unchanged. Docs and the config field description say a list is accepted; auto-discovery is still off the table because the wiring stays readable from one value. Fixes #1060 Refs #973 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Superseded by #1087, which is open as a draft with all CI green. The four seam PRs all touched What changed on the way, after reading the real consumer of this seam (the enterprise overlay on otari-ai
The branch is left in place rather than deleted. |
Description
Otari can be extended by pointing
OTARI_BOOTSTRAPat a trusted module that rebinds ports and adds routes at startup. Until now that setting took exactly one module, which fits one overlay per deployment but not a deployment that installs two independent extensions from different authors: one of them had to wrap the other.OTARI_BOOTSTRAP(and thebootstrapconfig field) now accepts a comma-separated list ofmodule:callableselectors, applied in the order written after the core defaults are bound. A later bind wins, as it did already. A blank entry anywhere in the list, a trailing comma included, refuses to start and names the position, and a second selector that cannot be loaded fails startup rather than quietly running with only the first. The startup summary names each selector with the ports it rebound and the routers it contributed.The list is explicit and ordered, so the whole wiring is still readable from one config value and nothing is discovered from installed packages, which keeps the no-auto-discovery rule in ARCHITECTURE.md intact. A single selector behaves exactly as before, including every error message.
This is one of the four seams needed so that budget alerts (#973) can ship as a plugin rather than in core. Refs #973.
How to test it locally
Automated:
make lint,make typecheck,make test-unit: the new cases live intests/unit/test_container.py(two selectors applied in order with a later bind winning and both routers recorded, blank middle entry, trailing comma, leading comma, and a failing second selector).uv run --frozen --no-dev python scripts/oss_edition_smoke.py: boots with no bootstrap at all, confirming the plain build is untouched.The integration suite (
make test-integration, which includestests/integration/test_bootstrap_overlay.py) was not run locally: the machine this was developed on has neither Docker nor a PostgreSQL server, so Testcontainers cannot start. CI runs it on this PR.By hand, from a checkout:
The startup log reads
Composition root: one:register rebound BillingPort; two:register rebound EntitlementPort. Then tryOTARI_BOOTSTRAP="one:register,": the gateway refuses to start withOTARI_BOOTSTRAP entry 2 of 2 is blank; remove the extra comma.PR Type
Relevant issues
Fixes #1060
Refs #973
Checklist
tests/unit,tests/integration).make lint,make typecheck,make test).make test-unitand the smoke gate ran locally;make test-integrationcould not (no Docker or PostgreSQL on the machine) and is left to CI.uv run python scripts/generate_openapi.py). Not applicable: no route or schema changed.AI Usage
AI Model/Tool used: Claude Fable 5.1 via Claude Code
Any additional AI details you'd like to share: Implementation, tests, docs and this description were written by the agent following the repo's
pr-cycle,backend-standardsandreviewskills. A human requested the change and set its scope.🤖 Generated with Claude Code