ADR-0130: Capability catalogue stays closed for 0.x¶
Status: Accepted (2026-10-05)
Relates to: ADR-0129 (HarnessServices freeze), core-boundary.md,
docs/oss-plan-review.md, the L4.5 Harness Hardening milestone.
Context¶
src/iris_harness/foundation/capabilities.py defines a sophisticated capability model
(provides/uses/requires, unmask grants, method effects, content classification,
fan-out for multiple providers of one capability) — and, as of this ADR, zero
CapabilitySpec registrations exist anywhere outside tests. The module's own docstring
still reads "Empty until rollout step 4 adds the first capabilities." The architecture
is well tested but not yet battle-tested by a real, independently packaged plugin.
The catalogue is centrally registered: every capability name a plugin might provide
or use must exist in core's catalogue. That gives IRIS core complete visibility into
every possible cross-plugin interface — valuable for governance, since the kernel can
reason about every capability's effect and classification without trusting a plugin's
say-so. The cost is that a third-party plugin author cannot invent a new capability
(e.g. weather.forecast, notes.search) without a PR against the core repo, even
though they implement it entirely in their own plugin.
Decision¶
-
Keep the capability catalogue closed through the 0.x line. Core registers every capability's schema (name, contract, effect, classification); a plugin, bundled or third-party, provides the implementation.
-
The L4.5 milestone's capability production exercise registers exactly one real capability,
weather.forecast, in core, implemented by the externaliris-weather-pluginrepo and consumed by a second external "trip advisory" plugin. This is the first production (non-test) use of the catalogue, and it is deliberately done through the closed-catalogue path — a core PR to name the capability, two external PRs to implement and consume it — so the friction of the 0.x model is felt firsthand before it's revisited. -
Revisit before 1.0. Once there is real usage data (how often would a third party actually want to invent a capability vs. extend an existing one), decide whether a namespaced, decentralized scheme (e.g. plugin-prefixed capability ids a plugin can register without a core PR) is worth the governance cost of capabilities core cannot fully reason about ahead of time.
Alternatives considered¶
- Open/decentralized capability registration now. Rejected for 0.x: the catalogue has never been used by a real plugin yet (A2 in the external review) — opening it up before the closed model has even been exercised once would be solving a problem with no evidence behind it, and it weakens the governance guarantee ("core knows every possible cross-plugin interface") before that guarantee has proven its worth.
- Leave the decision implicit. Rejected: the review correctly flagged that the policy was never stated explicitly, only implied by the code's current shape. An undocumented default is not a decision; a future contributor could "fix" the friction by quietly opening the catalogue without anyone having weighed the trade-off.
Consequences¶
- Positive: the capability model gets its first production exercise without simultaneously deciding how (or whether) to decentralize it; governance keeps full visibility into cross-plugin interfaces through 0.x.
- Negative: a third-party plugin author who wants a genuinely new capability during
0.x must file a core PR just to name it — documented explicitly in
core-boundary.mdso it isn't a surprise. - Reversible: nothing about the closed model is structurally locked in; the 1.0 revisit is a scheduled decision point, not a one-way door.
Files¶
src/iris_harness/foundation/capabilities.py— the catalogue this ADR keeps closed.docs/architecture/core-boundary.md— documents the hybrid schema/implementation split this ADR produces.