# Capability Spec Delta: api-plugin (extend-api-foundation-host-services) **Package**: `@suaveplan/api-plugin` **Status**: PROPOSED ## ADDED Requirements ### Requirement: PluginRegistry.seedServices bulk-registers entries before plugin init The package SHALL add `PluginRegistry.seedServices>(map: TMap): void`. Calling it stores every key/value pair in an internal seeded-services map. When `initialize()` later constructs per-plugin contexts, every seeded entry SHALL appear in `ctx.getService(name)` BEFORE any plugin's `onRegister` runs. Calling `seedServices` after `initialize()` has started SHALL raise `PluginError(PLUGIN_INVALID_STATE)`. #### Scenario: seeded service is resolvable from the first plugin's onRegister - **WHEN** `registry.seedServices({ app: stubApp })` is called, then a plugin with `onRegister(ctx) { ctx.getService("app") }` is registered, then `registry.initialize()` is awaited - **THEN** the plugin's `onRegister` resolves `stubApp` (no `undefined`) #### Scenario: later seed overrides earlier seed - **WHEN** `registry.seedServices({ logger: l1 })` is followed by `registry.seedServices({ logger: l2 })` before `initialize()` - **THEN** the next plugin's `ctx.getService("logger")` returns `l2` #### Scenario: seedServices after initialize raises PLUGIN_INVALID_STATE - **WHEN** `registry.initialize()` is awaited and then `registry.seedServices({ app: stubApp })` is called - **THEN** `PluginError(PLUGIN_INVALID_STATE)` is thrown **Verified by:** `src/registry/seed-services.test.ts::"seeded service resolvable from first plugin's onRegister"` AND `src/registry/seed-services.test.ts::"later seed overrides earlier"` AND `src/registry/seed-services.test.ts::"seedServices after initialize raises PLUGIN_INVALID_STATE"` --- ### Requirement: PluginRegistry exposes PLUGIN_INVALID_STATE in the code registry `PLUGIN_CODES` SHALL include `PLUGIN_INVALID_STATE` (taking the registry to 11 codes total). The code SHALL be raised by `seedServices` post-`initialize()`; existing 10 codes are preserved. #### Scenario: existing codes unchanged - **WHEN** the spec-conformance test enumerates `PLUGIN_CODES` - **THEN** the set is the union of the existing 10 codes plus `PLUGIN_INVALID_STATE` (no removals) **Verified by:** `src/api-plugin.spec-conformance.test.ts::"PLUGIN_CODES contains PLUGIN_INVALID_STATE alongside the existing 10"`