Contracts Boundary Architecture¶
This document describes the boundary between the contract package currently
published as victor-contracts and victor-ai (the framework runtime). New code
should use the semantic victor_contracts import alias and target the future
victor-contracts distribution name; victor_contracts remains a compatibility
namespace during the transition. External verticals depend only on the contract
package.
Overview¶
External Vertical (victor-coding, etc.)
│
▼
victor-contracts / victor-contracts compatibility
← Zero dependencies on victor-ai
│ Provides: VerticalBase, PluginContext, VictorPlugin,
│ ExtensionManifest, ToolProvider, MockPluginContext
▼
victor-ai ← Framework runtime
Provides: AgentOrchestrator, ProviderRegistry, ToolExecutor,
CapabilityNegotiator, entry point loading
Contract Package (victor-contracts/, future victor-contracts)¶
The contract package has zero dependencies on victor-ai. Its only runtime
dependency is typing-extensions>=4.9.
Key Protocols¶
| Protocol | File | Purpose |
|---|---|---|
VerticalBase |
victor_contracts/verticals/protocols/base.py |
Abstract base for all verticals |
PluginContext |
victor_contracts/core/plugins.py |
DI interface for plugin registration |
VictorPlugin |
victor_contracts/core/plugins.py |
Plugin lifecycle protocol |
ToolProvider |
victor_contracts/verticals/protocols/tools.py |
Tool registration protocol |
ExtensionManifest |
victor_contracts/verticals/manifest.py |
Capability declaration |
Testing Utilities¶
| Utility | File | Purpose |
|---|---|---|
MockPluginContext |
victor_contracts/testing/fixtures.py |
In-memory PluginContext for testing without victor-ai |
assert_valid_vertical() |
victor_contracts/testing/__init__.py |
Validate vertical implements SDK contract |
assert_import_boundaries() |
victor_contracts/testing/__init__.py |
Check vertical doesn't import victor internals |
validate_manifest() |
victor_contracts/verticals/validation.py |
Static manifest completeness check |
audit_vertical_dependencies() |
victor_contracts/verticals/validation.py |
Compare imports vs declared deps |
Entry Points¶
Verticals register via victor.plugins entry point group in pyproject.toml:
The framework discovers plugins via victor/framework/entry_point_loader.py
using importlib.metadata (NOT sys.path scanning). Additional entry point
groups:
victor.plugins— VictorPlugin implementationsvictor.extension.protocols— preferred protocol-provider entry pointsvictor.extension.capabilities— preferred capability-provider entry pointsvictor.sdk.protocols,victor.sdk.capabilities— legacy compatibility
groups supported during the contracts renamevictor.skills— Skill definitionsvictor.safety_rules,victor.tool_dependencies,victor.rl_configs,victor.escape_hatches,victor.commands,victor.prompt_contributors,victor.mode_configs,victor.workflow_providers,victor.team_spec_providers,victor.capability_providers,victor.service_providers
Manifest Validation Lifecycle¶
1. Definition @register_vertical(name="my-vert", version="1.0.0")
→ Attaches ExtensionManifest to class._victor_manifest
2. Discovery VerticalRegistry.discover_external_verticals()
→ Scans victor.plugins entry point group
3. Negotiation CapabilityNegotiator.negotiate(manifest)
→ Validates: API version, required extensions, extension_dependencies
→ File: victor/core/verticals/capability_negotiator.py
4. Activation VictorPlugin.register(context: PluginContext)
→ Plugin registers tools, verticals, commands via context
5. Runtime Orchestrator resolves tools via registered vertical providers
Extension Dependency Validation¶
Manifests can declare dependencies on other extensions:
ExtensionManifest(
name="my-vert",
extension_dependencies=[
ExtensionDependency(extension_name="lancedb", min_version=">=0.4"),
ExtensionDependency(extension_name="victor-coding", optional=True),
],
)
CapabilityNegotiator._validate_extension_dependencies() checks:
- Required deps are installed (hard error if missing)
- Version constraints are satisfied
- Optional deps produce warnings only
Import Boundaries¶
Layer rule enforced by scripts/check_imports.py:
Third-party vertical definition layers should import from victor_contracts only
(not victor.core, victor.agent, etc.). The five first-party domain verticals
are authored and published from the top-level verticals/ packages in this
monorepo; they are not bundled under a second victor/verticals/contrib/ source
tree. See ADR-007 for the
authoritative ownership and distribution boundary.
Contract boundary stability is enforced by contract shape tests at
tests/unit/contracts/test_contracts_contract_shapes.py.
External Vertical Development¶
- Depend on
victor-contracts>=X.Y(notvictor-ai) - Use
@register_vertical()decorator or set_victor_manifest - Implement
VictorPlugin.register(context)in your entry point - Declare
extension_dependenciesin manifest for third-party deps - Test with
MockPluginContextfromvictor_contracts.testing - Run
validate_manifest(MyVertical)andaudit_vertical_dependencies(src_dir, manifest)in CI