Extension points¶
Downstream repos extend otto from init modules — ordinary Python modules
named in the init list of .otto/settings.toml, imported during bootstrap
phase 2 (The command lifecycle). Registration is import-time and side-effect
based: an init module calls register_* functions (or applies decorators),
and from then on the new component behaves exactly like a built-in — same
registries, same CLI listing and completion, same error messages
(Registries and the pluggable CLI).
The seams¶
You want to add |
Register with |
Guide |
|---|---|---|
an |
||
an |
|
|
a top-level |
||
a CLI verb on a host class |
|
|
a host class (new |
|
|
an OS profile (defaults bundle) |
|
|
a connection (term) backend |
|
|
a file-transfer backend |
|
|
a shell dialect |
|
|
an embedded binary loader |
|
|
an embedded filesystem type |
|
|
a power controller |
|
|
products on hosts |
|
|
a host source (lab repository) |
||
a reservation backend |
|
|
per-host monitor parsers |
|
|
SNMP metric descriptors |
|
Options classes deserve a mention even though they aren’t a registry: a
repo-wide @options class shared by instructions and suites is the standard
way to give a whole project consistent CLI flags (Options classes).
What keeps third-party code honest¶
Symmetry. Built-ins use the same
register_*calls, so the public seams are exercised by otto itself on every run.Conformance helpers. For contract-shaped seams,
otto.testingshipsassert_*_conformsfunctions (e.g.assert_reservation_backend_conforms()) — one pytest test per backend catches every contract violation in one report.otto.examplesholds small, copyable reference implementations that otto’s own suite keeps green.Containment. A broken init module becomes one framed warning, not a broken CLI (The command lifecycle); a name collision is a loud error attributed to both registering modules (Registries and the pluggable CLI).
Schema visibility. Data-side extensions (profiles, preferences, custom settings tables) surface in
otto schema export, so editors validate them (Data at the boundary).