Rail-independence is the plan's spine: fedlearn rails verified NOT landed (no m2/m2-core, no capture/curator CLIs), so the wedge builds against frozen interfaces — m2/market-registry as registry of record, ApplyAdapter seam with local adapter now / m2core-sync stub, schemas frozen here with a fedlearn coordination note. Constitution check passed (1 justified deviation). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
43 lines
2.1 KiB
Markdown
43 lines
2.1 KiB
Markdown
# Contract: Apply Adapter (v1, frozen) — the fedlearn integration seam
|
|
|
|
The ONLY interface through which anything installs a Solution bundle onto a machine.
|
|
Freezing this seam is what lets the wedge ship before the fedlearn rails land (research.md
|
|
R5) and swap them in later without touching CLI or Store.
|
|
|
|
## Protocol (Python, `cli/src/m2_market/apply/base.py`)
|
|
|
|
```python
|
|
class ApplyAdapter(Protocol):
|
|
name: str # "local" | "m2core-sync"
|
|
def plan(self, bundle: Path, state: InstallState) -> Changeset: ...
|
|
def apply(self, changeset: Changeset) -> ApplyResult: ... # idempotent
|
|
def verify(self, bundle: Path, state: InstallState) -> bool: ...
|
|
def rollback(self, changeset: Changeset) -> None: ... # reversible (constitution VI)
|
|
```
|
|
|
|
- `Changeset`: declarative list of file placements / config merges / post-install checks
|
|
derived from the bundle's `recipe.yaml`, plus a `changeset_hash` recorded in
|
|
InstallState.
|
|
- `apply` MUST be idempotent (re-apply of an applied changeset = no-op success) and MUST
|
|
NOT require elevated fleet-wide operations (canary principle).
|
|
- `rollback` restores pre-apply state from the changeset's recorded backups.
|
|
|
|
## v1 implementations
|
|
|
|
### `local` (ships in this wedge)
|
|
Applies `payload/` into the operator's agent-home per `recipe.yaml` targets
|
|
(skills, prompts, configs, scripts), runs recipe post-install checks, records
|
|
InstallState. Works identically inside primus and agent-latest desktops (targets are
|
|
volume paths, not image paths) — satisfying "runtime-sync is the only universal path" in
|
|
spirit until the real one exists.
|
|
|
|
### `m2core-sync` (stub in this wedge)
|
|
Raises `RailsNotLanded` (CLI exit 6) with pointer to this contract. When fedlearn's
|
|
`m2-core-sync`/`m2-core pull --apply` lands, this adapter shells to it and merges its
|
|
state.json with InstallState. Acceptance for the swap (row 10 of plan sequencing): all
|
|
quickstart.md scenarios pass with `adapter = m2core-sync` unchanged.
|
|
|
|
## Selection
|
|
|
|
`config.toml: apply_adapter = "local"` (default in v1). Per-install override
|
|
`--adapter` for testing. The Store never selects an adapter — it inherits the CLI's.
|