UniteLabs
Reference

Review Checklist

Every connector best-practice rule in one list, with a stable ID to cite in reviews.

Each rule has a stable ID you can cite in a review comment or merge request, such as op-property-per-value. The Details column links to the page that explains the rule or shows how to apply it.

Naming

IDRuleDetails
name-title-case-display-nameDisplay name in Title Case with spacesNaming
name-hyphen-case-project-nameProject name in hyphen-caseNaming
name-snake-case-package-namePackage name in snake_caseNaming
name-no-unitelabs-in-project-nameDon't include unitelabs in the project or package nameNaming
name-no-rename-without-migration-planDon't rename a connector without a migration planNaming
name-folder-mirrors-classFeature folder and module are the snake_case form of the classNaming
name-short-file-namesShort file names that don't repeat the package nameNaming
name-suffix-by-roleController, Provider, or Service suffix by roleNaming
name-service-for-maintenance-featuresService for teaching, calibration, and server settingsNaming
name-actor-not-artifactName the actor, not the artifactNaming
name-no-feature-suffixNo Feature in class namesNaming
name-no-package-in-class-nameDon't repeat the package name in class namesNaming
name-no-abbreviationsSpell out full wordsNaming
name-get-prefixget_ prefix on unobservable propertiesNaming
name-subscribe-prefixsubscribe_ prefix on observable propertiesNaming
name-verb-for-commandsCommands start with an action verbNaming
name-full-words-for-identifiersFull words in method namesNaming
name-explicit-name-for-acronymsSet name= to keep an acronym uppercaseNaming
name-no-redundant-contextDon't repeat the feature's context in endpoint namesNaming
name-no-units-in-identifierNo units in identifiersNaming
name-one-name-everywhereOne name for file, class, and identifierNaming
name-normalize-vendor-terminologyUse the standard term, not the vendor'sDesigning Features
name-model-the-intent-not-the-mechanismName the operation the client cares aboutDesigning Features
name-standard-command-vocabularyUse a standard verb when one matchesNaming
name-check-sila-base-feature-repo-firstCheck the SiLA base feature repository firstNaming
name-parametrized-multi-instanceOne parametrized class per repeated moduleRepeated Modules
name-index-before-suffix<Noun><Index><Suffix>, index injected via name=Repeated Modules
name-slot-id-for-homogeneous-instancesOne feature with a slot parameter for interchangeable positionsRepeated Modules

Docstrings

IDRuleDetails
doc-google-style-docstringsGoogle style, no RST directivesDocstrings
doc-no-types-in-docstringNo types in Args:/Returns:Docstrings
doc-no-units-in-docstringNo units in docstrings; annotate a UnitDocstrings
doc-two-space-indent2-space indent under section headersDocstrings
doc-describe-what-and-whenFeature docstring says what and in which contextDocstrings
doc-args-section-pascalcaseArgs: entries in PascalCaseDocstrings
doc-params-match-signatureDocument parameters in signature orderDocstrings
doc-returns-section-pascalcaseReturns: entries in PascalCaseDocstrings
doc-yields-section-pascalcaseYields: for intermediate responsesDocstrings
doc-no-args-on-propertiesNo Args: on propertiesDocstrings
doc-no-returns-on-propertiesNo Returns: on propertiesDocstrings
doc-raises-to-override-descriptionRaises: only to override the default descriptionDocstrings
doc-no-generic-error-documentationDon't document errors that can happen anywhereDocstrings
doc-no-pythonic-examplesNo doctest examplesDocstrings
doc-sila-identifiers-in-descriptionsRefer to other endpoints by SiLA identifierDocstrings

Features

IDRuleDetails
feat-originator-reverse-domainReverse domain notation for originatorFeature Metadata
feat-no-default-originatorNever leave originator unsetFeature Metadata
feat-namespace-format-for-originator-categoryLowercase, digits, and dots onlyFeature Metadata
feat-category-domain-choiceOne functional domain; reuse existing categoriesFeature Metadata
feat-version-default-then-bumpLeave version unset until it bumps; major.minor onlyFeature Metadata
feat-maturity-level-draft-defaultLeave maturity_level unsetFeature Metadata
feat-be-opinionated-about-interface-designDesign for the user, not the vendor's manualDesigning Features
feat-one-feature-per-concernOne feature per concernDesigning Features
feat-register-before-yieldRegister features before yield appConnector Architecture

Endpoints

IDRuleDetails
op-observable-property-for-changing-valuesObservable for changing values, unobservable for static onesDesigning Endpoints
op-no-side-effects-in-propertiesProperties never change device stateDesigning Endpoints
op-property-per-valueOne property per piece of informationDesigning Endpoints
op-no-selector-parameterNo parameters that only select which value to returnDesigning Endpoints
op-long-or-risky-commands-observableObservable for movement or anything over ~300 msDesigning Endpoints
op-no-fake-progressNo fabricated progressDesigning Endpoints
op-indefinite-duration-start-stop-pairStart/stop pair for actions with no natural endDesigning Endpoints
op-cancellable-movement-commandsMovement commands can be cancelledDesigning Endpoints
op-prefer-idempotent-commandsCalling twice has the same effect as calling onceDesigning Endpoints
op-raise-on-already-in-progressRaise a clear error if the operation is already runningDesigning Endpoints
op-caller-can-always-tell-outcomeReturn normally on success, raise on failureDesigning Endpoints
op-recovery-through-normal-commandsEvery reachable state is recoverable through normal commandsDesigning Endpoints
op-no-boolean-success-responseNo Success: bool responsesDesigning Endpoints
op-bool-param-over-split-methodsOne bool parameter for a strictly two-state settingDesigning Endpoints
op-parameter-order-conventionAxes first, then by impact, duration lastDesigning Endpoints
op-execution-mode-by-repeatabilitySINGLE for movement; queue only idempotent commandsExecution Modes
op-expose-stateless-apiEndpoints are statelessDesigning Endpoints
op-enabled-for-device-variantsenabled= to hide endpoints a variant lacksDevice Variants
op-enable-as-overloadenabled= plus name= to overload an endpoint per variantDevice Variants

Data types and constraints

IDRuleDetails
dt-constraints-applied-to-all-valuesConstrain parameters and return values wherever it appliesConstraints and Units
dt-static-constraints-via-annotatedStatic constraints via typing.AnnotatedConstraints and Units
dt-runtime-constraints-on-startupDevice-dependent constraints in on_before_startConstraints and Units
dt-validation-error-for-fully-dynamic-constraintsValidator plus documented range for per-call limitsConstraints and Units
dt-binary-for-raw-databytes for raw payloadsDesigning Data Types
dt-content-type-for-known-binary-formatContentType for known binary formatsDesigning Data Types
dt-dataclass-for-grouped-dataDataclass for grouped valuesDesigning Data Types
dt-no-raw-xml-json-stringNo raw XML or JSON stringsDesigning Data Types
dt-no-nested-listsNo lists of listsDesigning Data Types
dt-enum-for-statusEnum for status and state valuesDesigning Data Types
dt-unit-constants-in-io-unitsDefine units once in io/units.pyConstraints and Units
dt-propagate-device-native-unitsExpose the unit the device usesDesigning Data Types
dt-fractional-unit-two-casesFractional units: expose as-is, or convert firmware workaroundsDesigning Data Types
dt-liquid-handler-origin-at-tip-bottomLiquid handler origin at the bottom of the tipDesigning Data Types

Input-output

IDRuleDetails
io-no-movement-on-transport-openNo physical movement when the transport opensConnector Architecture

Error handling

IDRuleDetails
err-only-execution-errors-in-decorator-or-raisesOnly declare execution errorsError Handling
err-define-error-per-failure-modeOne exception per expected failure modeError Handling
err-surface-hardware-error-codesInclude the device's error code in the messageError Handling
err-actionable-runtime-messagesSay what happened and what to try nextError Handling
err-no-all-errors-declaredOnly declare errors the caller can react toError Handling
err-start-real-mode-failedStay in simulation if real mode can't connectTesting

Project structure

IDRuleDetails
proj-features-import-from-io-not-reversefeatures/ imports from io/, never the reverseConnector Architecture
proj-io-has-no-sila-knowledgeio/ has no knowledge of SiLAConnector Architecture
proj-no-helpers-in-featureBusiness logic lives in io/, not in feature helpersConnector Architecture
proj-delegate-protocol-by-moduleSplit a long protocol into per-module delegatesProject Structure
proj-protocol-layer-mirrors-vendor-docsName io/ commands as the vendor doesProject Structure
proj-dedicated-config-pyConfiguration in config.pyProject Structure
proj-no-commit-config-jsonDon't commit config.jsonProject Structure
proj-hardware-errors-in-io-errorsHardware exceptions in io/errors.pyProject Structure
proj-debugging-commands-in-own-featureDebugging commands in their own featureProject Structure
proj-extend-standard-feature-in-placeAdd device-specific endpoints to the standard featureProject Structure
proj-public-top-private-bottomConstructor, properties, public, then private methodsProject Structure
proj-descriptive-private-method-namesSelf-descriptive private method namesProject Structure

Testing

IDRuleDetails
test-always-include-simulation-modeEvery connector runs without hardwareTesting
test-simulate-at-protocol-level-not-feature-levelSimulate in the protocol, not in featuresTesting
test-simulation-true-by-defaultSimulation mode defaults to onTesting
test-simulation-stubs-in-ioSimulation stubs live in io/Testing
test-mirror-packagetests/ mirrors the package layoutTesting
test-protocol-with-stubbed-responsesUnit-test every io/ method with stubbed responsesTesting

Last updated