Architecture¶
Layout¶
The two contracts¶
The project speaks to two structurally different Hubs, so it carries two clients and two pipelines rather than one abstraction forced to fit both:
.xdeploy Hub |
Real xcore-team/marketplace | |
|---|---|---|
| Client | agent/hub_client.py → HubClient protocol + HttpHubClient |
agent/marketplace_client.py → MarketplaceClient |
| Pipeline | agent/pipeline.py → DeploymentRunner |
agent/marketplace_pipeline.py → MarketplaceDeploymentRunner |
| Watch loop | agent/watcher.py → Watcher |
agent/marketplace_watcher.py → MarketplaceWatcher |
| Status | Proposed REST contract, not yet built | Real, validated backend |
| Artifact | Encrypted .xdeploy (tar → zstd → AES-256-GCM, Ed25519-signed) |
Plain ZIP (GitHub zipball), HMAC-SHA256-signed |
| Orchestration | install.yaml bundled inside the artifact |
install.yaml supplied locally by the operator |
Everything else — the install driver, supervisors, provisioners, state store, garbage collector, schemas — is shared between the two flows.
Dependencies¶
- pydantic —
install.yaml/manifest.jsonschemas, validated before anything executes - httpx — async HTTP for both Hub clients (tests swap in
httpx.MockTransport) - cryptography — Ed25519, AES-256-GCM, content digests
- zstandard —
.xdeploycompression - typer + rich — CLI and console output
- pyyaml — plan/config parsing
XCore Hub API contract (proposed, not validated)¶
XCore Hub doesn't exist yet, so HttpHubClient is implemented against a
REST contract inferred from this project's architecture notes rather than
a published spec. It's a concrete, working starting point — build the real
Hub against these routes, or edit hub_client.py once the real ones are
decided. Nothing else in xcore-agent needs to change either way: the
pipeline, watcher, and CLI all depend on the HubClient protocol, not on
this implementation.
All bodies are JSON; binary fields (signature, signer_public_key, dek,
artifact_signature) are base64; auth is Authorization: Bearer <access_token>
except on /v1/auth itself.
A 401/403 from /v1/auth or /v1/deployments/authorize raises
AuthenticationError; any other non-2xx raises ArtifactError (or
DeploymentError for /v1/auth and /v1/deployments/report) with the
status code and the response's error field, if present, in the message.
tests/test_http_hub_client.py exercises all of this against
httpx.MockTransport — no network, no real Hub needed to verify the client
speaks its own contract correctly.
See The real marketplace flow for the contrast with the validated marketplace contract.