plesty.sdk.commands.check

Check a module for plesty standard.

Attributes

_REQUIRED_PROJECT_FIELDS

_NAME_PATTERN

_VERSION_PATTERN

_PLESTY_LIB_PREFIXES

_REQUIRED_LICENSE_FILES

_COVERAGE_THRESHOLD

_ANALYZER_PIPELINE_GATES

_EXPERIMENT_PIPELINE_GATES

_gate_guidance_cache

_PROTECTED_SCHEMA_NAMES

_DEVICE_DOCS_PROBE

_WRITE_MODE_CHARS

_MANIFEST_FIELDS

_MANIFEST_TIMEOUT

_DEFAULT_SCHEMA_GROUP

Exceptions

GateNotApplicable

The gate does not apply to this module, and says so as a skip.

Functions

_gate_guidance(→ dict[str, Any])

Load the per-gate failure guidance from the packaged asset (cached).

_echo_pass(→ None)

Echo a gate progress line unless --quiet is active.

_run_gate(→ None)

Run one gate, record its outcome, and explain a failure.

_standard_for_version(→ str | None)

Map a version string to its compliance standard, or None when unparseable.

derive_standard(→ tuple[str, str])

Resolve the compliance standard for a project.

check_command(→ None)

Check compliance of a HUB module with the Plesty standard.

_gate_sequence(→ tuple[str, Ellipsis])

Return every gate key this standard runs, in order.

check_metadata(→ None)

Validate required pyproject.toml fields and plesty namespace conventions.

run_linter(→ None)

Run ruff linter (E, F, W, D rules) on the project directory.

run_formatter_check(→ None)

Check ruff formatting without modifying files.

run_type_checker(→ None)

Run mypy type checker over the plesty namespace module source.

check_api_interfaces(→ None)

Verify public classes inherit from the appropriate plesty-lib base class.

_collect_plesty_lib_imports(→ set[str])

Return names imported from plesty.lib.* in the given AST.

_resolve_base_name(→ str)

Extract the simple name from a base-class AST node.

check_data_compliance(→ None)

Verify the module respects the unified plesty-lib data-layer schemas.

_missing_return_annotations(→ list[str])

Rule 1: report public functions without an explicit return annotation.

_shadowed_schema_classes(→ list[str])

Rule 2: report class definitions that shadow a plesty-lib schema model.

check_documentation(→ None)

Check docs directory structure and that CHANGELOG.md is current.

_assert_changelog_updated(→ None)

Raise if Python source files changed since the last git tag without a CHANGELOG update.

check_dependency_coexistence(→ None)

Reject exact version pins (==) in project dependencies.

check_test_coverage(→ None)

Run pytest with coverage and enforce the 80% threshold.

_measured_coverage(→ float | None)

Extract the total coverage percentage from pytest-cov's terminal output.

check_semantic_versioning(→ None)

Diff the public API against the latest release published on PyPI.

_check_tag_freshness(→ None)

Remind the developer to tag a release if commits exist since the last tag.

check_licensing(→ None)

Verify licensing declarations and REUSE compliance.

_check_authorship_currency(→ None)

Ensure unpushed commit authors are credited on the files they changed.

check_vulnerability_audit(→ None)

Audit declared dependencies for known CVEs using pip-audit.

check_docs_build(→ None)

Build the Sphinx documentation and fail on any errors or warnings.

_is_device_module(→ bool)

Return True when [tool.plesty] module_type = "device" is declared.

_run_mock_pipeline_drivers(→ list[str])

Return the names of test functions that drive run_mock_pipeline().

check_device_api_pipeline(→ None)

Gate d1: Verify device modules run the standard mock pipeline.

check_device_status_contract(→ None)

Gate d2: Verify device telemetry overrides keep their schema annotations.

_status_contract_violations(→ list[str])

Report device-class telemetry overrides with wrong return annotations.

check_device_docs(→ None)

Gate d3: Verify device modules are documentable with zero effort.

_is_analyzer_module(→ bool)

Return True when [tool.plesty] module_type = "analyzer" is declared.

check_analyzer_contract(→ None)

Gate a1: Verify analyzer modules implement the AnalyzerPipeline test suite.

_is_experiment_module(→ bool)

Return True when [tool.plesty] module_type = "experiment" is declared.

check_experiment_contract(→ None)

Gate e1: Verify experiment modules implement the ExperimentPipeline test suite.

check_experiment_persistence(→ None)

Gate e2: Verify experiment modules persist results through the data layer.

check_experiment_manifest(→ None)

Gate e3: Verify an experiment module declares how it is run.

_read_manifest(→ dict[str, Any])

Run python -m <module> --manifest and return the document it printed.

_manifest_problems(→ list[str])

Return what the manifest document itself gets wrong.

_parameter_problems(→ list[str])

Return what one declared configuration parameter is missing.

_schema_drift(→ list[str])

Return where the schema and the module's own configuration disagree.

_config_keys(→ set[str])

Return the keys a configuration document sets, as the schema addresses them.

_declared_keys(→ set[str])

Return every key the schema declares, addressed as a renderer writes it.

check_field_test_findings(→ None)

Gate f1: no published field test report holds an error finding.

_adhoc_persistence_calls(→ list[str])

Report direct persistence calls that bypass save_result.

_describe_persistence_call(→ str)

Return a description of node when it is an ad-hoc persistence call.

_has_write_mode(→ bool)

Return True when a call's mode argument statically requests writing.

_module_name_from_toml(→ str)

Derive the Python module name from the pyproject.toml package name.

_import_path_from_toml(→ str)

Return the import path the package is served with by python -m.

_tail_text(→ str)

Return a compact tail of non-empty build output.

_run_subprocess(→ None)

Run a subprocess and exit with its return code on failure.

Module Contents

plesty.sdk.commands.check._REQUIRED_PROJECT_FIELDS = ('name', 'description', 'authors', 'requires-python', 'license')
plesty.sdk.commands.check._NAME_PATTERN
plesty.sdk.commands.check._VERSION_PATTERN
plesty.sdk.commands.check._PLESTY_LIB_PREFIXES = ('plesty.lib', 'plesty_lib', 'plestylib')
plesty.sdk.commands.check._REQUIRED_LICENSE_FILES = ('LICENSE',)
plesty.sdk.commands.check._COVERAGE_THRESHOLD = 80
plesty.sdk.commands.check._ANALYZER_PIPELINE_GATES = ('test_analyzer_subclass', 'test_schema_integrity', 'test_analyze_signature',...
plesty.sdk.commands.check._EXPERIMENT_PIPELINE_GATES = ('test_experiment_subclass', 'test_plan_deterministic', 'test_plan_ops_resolve',...
plesty.sdk.commands.check._gate_guidance_cache: dict[str, Any] | None = None
plesty.sdk.commands.check._gate_guidance() → dict[str, Any]

Load the per-gate failure guidance from the packaged asset (cached).

Return type:

dict[str, Any]

plesty.sdk.commands.check._echo_pass(message: str) → None

Echo a gate progress line unless –quiet is active.

Parameters:

message (str)

Return type:

None

exception plesty.sdk.commands.check.GateNotApplicable

Bases: Exception

The gate does not apply to this module, and says so as a skip.

A device gate on an analyzer has not passed; it has not run. Recording it as a pass would let check.json claim a device contract the module was never held to, and a page that labels only what passed reads as though the rest passed too.

The message is the full CLI line, so the terminal output is unchanged from when each gate echoed it itself.

Initialize self. See help(type(self)) for accurate signature.

plesty.sdk.commands.check._run_gate(key: str, gate: collections.abc.Callable[[], None], report: plesty.sdk.report.CheckReport | None = None) → None

Run one gate, record its outcome, and explain a failure.

Parameters:
  • key (str) – Gate key into the packaged guidance asset.

  • gate (collections.abc.Callable[[], None]) – Zero-argument callable executing the gate.

  • report (plesty.sdk.report.CheckReport | None) – Collector for reports/check.json. Outcomes are recorded whether the gate passes, skips or fails — a run that stopped early must not read as a clean sweep of a shorter sequence.

Return type:

None

plesty.sdk.commands.check._standard_for_version(version: str) → str | None

Map a version string to its compliance standard, or None when unparseable.

Parameters:

version (str) – Version string such as 0.2.1 or v1.0.0.

Return type:

str | None

plesty.sdk.commands.check.derive_standard(project_dir: pathlib.Path, pyproject_toml: dict[str, Any]) → tuple[str, str]

Resolve the compliance standard for a project.

An explicit [tool.plesty] standard always wins. Without it, the standard is derived from the declared release version so that shared prototypes ramp up automatically (plesty-sdk#19): < 0.1.0 → pixel, < 1.0.0 → nebula, >= 1.0.0 → quantum. For projects with a dynamic version (versioningit), the latest git tag is used; a project without any release tag is a fresh prototype and maps to pixel. A project that declares neither a static nor a dynamic version falls back to quantum, the conservative default.

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Returns:

A (standard, reason) tuple; the reason is human-readable and echoed by plesty check.

Return type:

tuple[str, str]

plesty.sdk.commands.check.check_command(context: plesty.sdk.context.ApplicationContext, standard: Literal['pixel', 'nebula', 'quantum'] | None, no_report: bool) → None

Check compliance of a HUB module with the Plesty standard.

Enforcement tiers: pixel runs Metadata & Code Hygiene only (fast, suitable for pre-commit); nebula runs gates 1–6 without network access and is the standard enforced by the pre-push git hook installed by plesty init; quantum runs all gates locally, including the [SDK+CI] tier, for full verification.

Unless --no-report is given, the run writes reports/check.json — the module’s standard-gate results in the same envelope the field test publishes, so a quality page renders both as one story.

Parameters:
Return type:

None

plesty.sdk.commands.check._gate_sequence(standard: str) → tuple[str, Ellipsis]

Return every gate key this standard runs, in order.

Used to record the gates a failed run never reached: a partial report listing only the gates that happened to run before the failure would read as a clean sweep of a shorter sequence.

Parameters:

standard (str) – The resolved compliance standard.

Return type:

tuple[str, Ellipsis]

plesty.sdk.commands.check.check_metadata(project_dir: pathlib.Path, pyproject_toml: dict[str, Any]) → None

Validate required pyproject.toml fields and plesty namespace conventions.

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

None

plesty.sdk.commands.check.run_linter(project_directory: pathlib.Path) → None

Run ruff linter (E, F, W, D rules) on the project directory.

Parameters:

project_directory (pathlib.Path) – The target project directory.

Return type:

None

plesty.sdk.commands.check.run_formatter_check(project_directory: pathlib.Path) → None

Check ruff formatting without modifying files.

Parameters:

project_directory (pathlib.Path) – The target project directory.

Return type:

None

plesty.sdk.commands.check.run_type_checker(project_directory: pathlib.Path) → None

Run mypy type checker over the plesty namespace module source.

Parameters:

project_directory (pathlib.Path) – The target project directory.

Return type:

None

plesty.sdk.commands.check.check_api_interfaces(project_dir: pathlib.Path, pyproject_toml: dict[str, Any]) → None

Verify public classes inherit from the appropriate plesty-lib base class.

Classes that import from plesty.lib.* must inherit from one of the imported base classes. The specific base class (e.g. BaseDeviceSyncModel) is enforced implicitly: if it is imported and not used as a base, the check fails.

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

None

plesty.sdk.commands.check._collect_plesty_lib_imports(tree: ast.AST) → set[str]

Return names imported from plesty.lib.* in the given AST.

Parameters:

tree (ast.AST) – Parsed AST of a Python source file.

Return type:

set[str]

plesty.sdk.commands.check._resolve_base_name(node: ast.expr) → str

Extract the simple name from a base-class AST node.

Parameters:

node (ast.expr) – An AST expression representing a base class.

Return type:

str

plesty.sdk.commands.check.check_data_compliance(project_dir: pathlib.Path, pyproject_toml: dict[str, Any]) → None

Verify the module respects the unified plesty-lib data-layer schemas.

Two static rules apply to every module (plesty-sdk#17, follow-up to plesty-lib#4):

  1. Return annotations: every public function or method declares an explicit return type annotation.

  2. No schema shadowing (except plesty-lib itself): the module must not define its own classes named after the plesty-lib schema models (_PROTECTED_SCHEMA_NAMES) — that silently forks the data contract.

Module-type-specific data rules live in their own gates: d2 (device status contract) and e2 (experiment persistence).

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

None

plesty.sdk.commands.check._PROTECTED_SCHEMA_NAMES = ('ConfigParameter', 'ConfigGroup', 'Command', 'ConfigSystem', 'FuncMeta', 'FuncParam',...
plesty.sdk.commands.check._missing_return_annotations(tree: ast.AST, rel_path: pathlib.Path) → list[str]

Rule 1: report public functions without an explicit return annotation.

Parameters:
  • tree (ast.AST) – Parsed AST of a module source file.

  • rel_path (pathlib.Path) – Project-relative path used in violation messages.

Return type:

list[str]

plesty.sdk.commands.check._shadowed_schema_classes(tree: ast.AST, rel_path: pathlib.Path) → list[str]

Rule 2: report class definitions that shadow a plesty-lib schema model.

Parameters:
  • tree (ast.AST) – Parsed AST of a module source file.

  • rel_path (pathlib.Path) – Project-relative path used in violation messages.

Return type:

list[str]

plesty.sdk.commands.check.check_documentation(project_dir: pathlib.Path) → None

Check docs directory structure and that CHANGELOG.md is current.

Parameters:

project_dir (pathlib.Path) – Root directory of the target project.

Return type:

None

plesty.sdk.commands.check._assert_changelog_updated(project_dir: pathlib.Path) → None

Raise if Python source files changed since the last git tag without a CHANGELOG update.

Parameters:

project_dir (pathlib.Path) – Root directory of the target project.

Return type:

None

plesty.sdk.commands.check.check_dependency_coexistence(pyproject_toml: dict[str, Any]) → None

Reject exact version pins (==) in project dependencies.

Parameters:

pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

None

plesty.sdk.commands.check.check_test_coverage(project_dir: pathlib.Path, report: plesty.sdk.report.CheckReport | None = None) → None

Run pytest with coverage and enforce the 80% threshold.

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • report (plesty.sdk.report.CheckReport | None) – When given, the measured percentage is recorded on it. The number is worth publishing: a threshold tells a reader the module cleared a bar, the percentage tells them by how much.

Return type:

None

plesty.sdk.commands.check._measured_coverage(output: str) → float | None

Extract the total coverage percentage from pytest-cov’s terminal output.

Parameters:

output (str) – Captured stdout of the coverage run.

Returns:

The percentage, or None when the output carries no total — a run that failed before collecting has no coverage to report, and zero would be a measurement rather than the absence of one.

Return type:

float | None

plesty.sdk.commands.check.check_semantic_versioning(project_dir: pathlib.Path, pyproject_toml: dict[str, Any] | None = None) → None

Diff the public API against the latest release published on PyPI.

Breaking API changes require a version bump beyond the published release (a minor bump before 1.0.0, a major bump afterwards), witnessed by a git tag. The gate is advisory in local runs and authoritative in CI (CI env set). When the package is unpublished or PyPI is unreachable, it falls back to the tag-freshness reminder.

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • pyproject_toml (dict[str, Any] | None) – Parsed pyproject.toml content; when omitted, only the tag-freshness reminder runs.

Return type:

None

plesty.sdk.commands.check._check_tag_freshness(project_dir: pathlib.Path) → None

Remind the developer to tag a release if commits exist since the last tag.

Fallback for unpublished packages and offline runs, where the API diff against PyPI is not possible.

Parameters:

project_dir (pathlib.Path) – Root directory of the target project.

Return type:

None

plesty.sdk.commands.check.check_licensing(project_dir: pathlib.Path, pyproject_toml: dict[str, Any]) → None

Verify licensing declarations and REUSE compliance.

Checks that pyproject.toml declares a license, that a root LICENSE file exists (so forges such as GitLab detect the license), and that the project is compliant with the REUSE specification via reuse lint. The deep dependency tree scan (CI part of this gate) runs in plesty-ci.

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

None

plesty.sdk.commands.check._check_authorship_currency(project_dir: pathlib.Path) → None

Ensure unpushed commit authors are credited on the files they changed.

Part of the Licensing gate. Runs locally only (a no-op in CI, and when there is no base branch to compare against). When a commit author is not yet listed as a contributor or copyright holder on a Python file they changed, the push is blocked until plesty license author records them.

Parameters:

project_dir (pathlib.Path) – Root directory of the target project.

Return type:

None

plesty.sdk.commands.check.check_vulnerability_audit(project_dir: pathlib.Path) → None

Audit declared dependencies for known CVEs using pip-audit.

Exports a flat requirements.txt from uv.lock and runs pip-audit against it. Requires network access to query the OSV vulnerability database.

Parameters:

project_dir (pathlib.Path) – Root directory of the target project.

Return type:

None

plesty.sdk.commands.check.check_docs_build(context: plesty.sdk.context.ApplicationContext) → None

Build the Sphinx documentation and fail on any errors or warnings.

Runs locally and in merge-request pipelines, so docs-breaking changes fail before they merge. Skipped in CI branch pipelines (CI=true without CI_PIPELINE_SOURCE=merge_request_event) because hub-deploy-docs builds and deploys the docs there as a dedicated pipeline job.

Parameters:

context (plesty.sdk.context.ApplicationContext) – The application context for the target project.

Return type:

None

plesty.sdk.commands.check._is_device_module(pyproject_toml: dict[str, Any]) → bool

Return True when [tool.plesty] module_type = "device" is declared.

Parameters:

pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

bool

plesty.sdk.commands.check._run_mock_pipeline_drivers(project_dir: pathlib.Path) → list[str]

Return the names of test functions that drive run_mock_pipeline().

Read with ast rather than by grepping: a name in a docstring or a comment is not a test that runs, and accepting one would let a module claim the contract without exercising it.

Parameters:

project_dir (pathlib.Path) – Root directory of the target project.

Returns:

Test function names containing a run_mock_pipeline call, in the order found.

Return type:

list[str]

plesty.sdk.commands.check.check_device_api_pipeline(project_dir: pathlib.Path, pyproject_toml: dict[str, Any]) → None

Gate d1: Verify device modules run the standard mock pipeline.

Modules that do not declare module_type = "device" in [tool.plesty] are silently skipped. For device modules, tests/ must contain a test calling run_mock_pipeline(), and it must pass without hardware.

One call runs all eight gates and reports every failure it found, so the eight forwarding functions this gate used to require were boilerplate that said nothing a single call does not. plesty init mock-test generates the test from the module’s own declarations.

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

None

plesty.sdk.commands.check.check_device_status_contract(project_dir: pathlib.Path, pyproject_toml: dict[str, Any]) → None

Gate d2: Verify device telemetry overrides keep their schema annotations.

Modules that do not declare module_type = "device" in [tool.plesty] are silently skipped. For device modules, overrides of status() must be annotated to return DeviceStatus and overrides of device_state() to return str, so consumers can rely on the plesty-lib telemetry schema (plesty-sdk#17, follow-up to plesty-lib#4).

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

None

plesty.sdk.commands.check._status_contract_violations(tree: ast.AST, rel_path: pathlib.Path) → list[str]

Report device-class telemetry overrides with wrong return annotations.

Parameters:
  • tree (ast.AST) – Parsed AST of a module source file.

  • rel_path (pathlib.Path) – Project-relative path used in violation messages.

Return type:

list[str]

plesty.sdk.commands.check._DEVICE_DOCS_PROBE = Multiline-String
Show Value
"""
import tomllib
from plesty.sdk.commands.docs.generate import load_doc_device, render_device_pages

with open("pyproject.toml", "rb") as fh:
    pyproject = tomllib.load(fh)

device = load_doc_device(pyproject)
model = device.doc_model()
if not model.standard_methods:
    raise SystemExit("doc_model().standard_methods is empty")
if not model.parameters and not model.functions:
    raise SystemExit("device documents neither parameters nor functions")
render_device_pages(model)  # must render without error
print("D3_OK")
"""
plesty.sdk.commands.check.check_device_docs(project_dir: pathlib.Path, pyproject_toml: dict[str, Any]) → None

Gate d3: Verify device modules are documentable with zero effort.

Modules that do not declare module_type = "device" in [tool.plesty] are silently skipped. For device modules, the package must import, expose a hardware-free DocDevice/Device factory, and produce a populated doc_model() that renders into the standard reference pages — so plesty docs can generate Parameters / Functions / Standard Methods pages without any hand-written content (plesty-sdk#18).

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

None

plesty.sdk.commands.check._is_analyzer_module(pyproject_toml: dict[str, Any]) → bool

Return True when [tool.plesty] module_type = "analyzer" is declared.

Parameters:

pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

bool

plesty.sdk.commands.check.check_analyzer_contract(project_dir: pathlib.Path, pyproject_toml: dict[str, Any]) → None

Gate a1: Verify analyzer modules implement the AnalyzerPipeline test suite.

Modules that do not declare module_type = "analyzer" in [tool.plesty] are silently skipped. For analyzer modules, all five contract gate test functions must be present in tests/ and pass on schema-generated synthetic inputs — they validate the package against the plesty.lib.analyzer.Analyzer contract (public subclass, schema integrity, analyze-signature match, mock round-trip, provenance stamp).

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

None

plesty.sdk.commands.check._is_experiment_module(pyproject_toml: dict[str, Any]) → bool

Return True when [tool.plesty] module_type = "experiment" is declared.

Parameters:

pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

bool

plesty.sdk.commands.check.check_experiment_contract(project_dir: pathlib.Path, pyproject_toml: dict[str, Any]) → None

Gate e1: Verify experiment modules implement the ExperimentPipeline test suite.

Modules that do not declare module_type = "experiment" in [tool.plesty] are silently skipped. For experiment modules, all five contract gate test functions must be present in tests/ and pass without hardware — they validate the package against the plesty.lib.experiment.Experiment contract (single public subclass, deterministic build_plan(), resolvable step operations, JSON-serializable plans, async lifecycle hooks).

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

None

plesty.sdk.commands.check.check_experiment_persistence(project_dir: pathlib.Path, pyproject_toml: dict[str, Any]) → None

Gate e2: Verify experiment modules persist results through the data layer.

Modules that do not declare module_type = "experiment" in [tool.plesty] are silently skipped. For experiment modules, direct persistence calls — np.save/np.savez/np.savez_compressed, pickle.dump, h5py.File opened with a write mode, and builtin open with a write mode — are rejected in the module package: results must be persisted via plesty.lib.data.save_result/ResultDocument (plesty-sdk#17, follow-up to plesty-lib#4). Calls whose mode cannot be resolved statically are left alone.

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

None

plesty.sdk.commands.check._WRITE_MODE_CHARS
plesty.sdk.commands.check._MANIFEST_FIELDS = ('module', 'title', 'config', 'run_root', 'schema')
plesty.sdk.commands.check._MANIFEST_TIMEOUT = 60
plesty.sdk.commands.check.check_experiment_manifest(project_dir: pathlib.Path, pyproject_toml: dict[str, Any]) → None

Gate e3: Verify an experiment module declares how it is run.

Modules that do not declare module_type = "experiment" in [tool.plesty] are silently skipped. For experiment modules, python -m <module> --manifest must print the document described in plesty.lib.experiment.Manifest — the run command, the run root, the environment the run reads and the configuration schema — so a console can offer the experiment’s settings without being taught them one module at a time.

Two things are checked beyond the document’s shape, and they are the reason the gate exists:

  • Every parameter says what it is. A control rendered without a dtype and a description is a box with a name on it, and a bounded one without a unit shows bare numbers. unit="" is an answer — a count has no unit — but leaving it unset is not.

  • The schema and the shipped configuration agree. A key the configuration sets and the schema omits cannot be edited; a key the schema declares and no configuration sets renders as a setting that does nothing. A schema nobody keeps current is worse than none, because a console renders it as fact.

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Raises:
  • GateNotApplicable – If the module is not an experiment module.

  • click.ClickException – If the manifest cannot be produced, is malformed, or disagrees with the module’s own configuration files.

Return type:

None

plesty.sdk.commands.check._read_manifest(project_dir: pathlib.Path, module: str) → dict[str, Any]

Run python -m <module> --manifest and return the document it printed.

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • module (str) – The module’s import path.

Returns:

The parsed document.

Raises:

click.ClickException – If the command fails, times out, or prints something that is not a JSON object.

Return type:

dict[str, Any]

plesty.sdk.commands.check._manifest_problems(document: dict[str, Any], module: str) → list[str]

Return what the manifest document itself gets wrong.

Parameters:
  • document (dict[str, Any]) – The parsed manifest.

  • module (str) – The module’s import path, which the manifest must name.

Returns:

One line per problem; empty when the document is well formed.

Return type:

list[str]

plesty.sdk.commands.check._parameter_problems(group: str, entry: Any) → list[str]

Return what one declared configuration parameter is missing.

Parameters:
  • group (str) – The group it is declared under.

  • entry (Any) – The parameter mapping.

Returns:

One line per problem.

Return type:

list[str]

plesty.sdk.commands.check._schema_drift(project_dir: pathlib.Path, document: dict[str, Any]) → list[str]

Return where the schema and the module’s own configuration disagree.

Parameters:
  • project_dir (pathlib.Path) – Root directory of the target project.

  • document (dict[str, Any]) – The parsed manifest.

Returns:

One line per key that only one of the two knows about.

Return type:

list[str]

plesty.sdk.commands.check._config_keys(config: dict[str, Any], groups: set[str]) → set[str]

Return the keys a configuration document sets, as the schema addresses them.

Only the two levels a schema describes are walked: a top-level value, and the members of a declared group. What lies inside an open-ended document is the experiment’s own business.

Parameters:
  • config (dict[str, Any]) – The loaded configuration.

  • groups (set[str]) – The non-default group names the schema declares.

Returns:

The keys, group.parameter for grouped ones.

Return type:

set[str]

plesty.sdk.commands.check._declared_keys(schema: dict[str, Any]) → set[str]

Return every key the schema declares, addressed as a renderer writes it.

Parameters:

schema (dict[str, Any]) – The manifest’s schema block.

Returns:

The declared keys.

Return type:

set[str]

plesty.sdk.commands.check._DEFAULT_SCHEMA_GROUP = 'default'
plesty.sdk.commands.check.check_field_test_findings(project_dir: pathlib.Path) → None

Gate f1: no published field test report holds an error finding.

A field test writes reports/<instrument>/field-test.json after running against real hardware. An error finding in one means the module declares an API the instrument does not have — a parameter the hardware refuses, or one it will not answer. The module is telling every caller that something exists which does not, so it must not be published in that state.

A module that has never been field-tested publishes no report and skips this gate. Absence is the honest rendering: “never run” and “ran and found nothing” are different facts, and treating them alike is how an untested module reads as a verified one.

Parameters:

project_dir (pathlib.Path) – Root directory of the target project.

Raises:
  • GateNotApplicable – If the module publishes no field test report.

  • click.ClickException – If any report holds an error finding, or a report cannot be read.

Return type:

None

plesty.sdk.commands.check._adhoc_persistence_calls(tree: ast.AST, rel_path: pathlib.Path) → list[str]

Report direct persistence calls that bypass save_result.

Parameters:
  • tree (ast.AST) – Parsed AST of a module source file.

  • rel_path (pathlib.Path) – Project-relative path used in violation messages.

Return type:

list[str]

plesty.sdk.commands.check._describe_persistence_call(node: ast.Call) → str

Return a description of node when it is an ad-hoc persistence call.

Parameters:

node (ast.Call) – A call expression to classify.

Returns:

A short human-readable description, or "" when the call is fine.

Return type:

str

plesty.sdk.commands.check._has_write_mode(node: ast.Call, default_write: bool = False) → bool

Return True when a call’s mode argument statically requests writing.

The mode is taken from the second positional argument or the mode keyword. A missing mode means read-only; a mode that is not a string constant cannot be judged statically and is treated as read-only.

Parameters:
  • node (ast.Call) – The open/h5py.File call expression.

  • default_write (bool) – Result to return when no mode argument is present.

Return type:

bool

plesty.sdk.commands.check._module_name_from_toml(pyproject_toml: dict[str, Any]) → str

Derive the Python module name from the pyproject.toml package name.

Parameters:

pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

str

plesty.sdk.commands.check._import_path_from_toml(pyproject_toml: dict[str, Any]) → str

Return the import path the package is served with by python -m.

[tool.plesty] module wins where a module declares one; otherwise it is the package name under the plesty namespace, the convention every module follows (plesty-pol-pl → plesty.pol_pl).

Parameters:

pyproject_toml (dict[str, Any]) – Parsed pyproject.toml content.

Return type:

str

plesty.sdk.commands.check._tail_text(text: str, max_lines: int = 20) → str

Return a compact tail of non-empty build output.

Parameters:
  • text (str)

  • max_lines (int)

Return type:

str

plesty.sdk.commands.check._run_subprocess(cmd: list[str], gate: str, cwd: pathlib.Path | None = None) → None

Run a subprocess and exit with its return code on failure.

Parameters:
  • cmd (list[str]) – Command and arguments to run.

  • gate (str) – Gate name used in error messages.

  • cwd (pathlib.Path | None) – Working directory for the subprocess.

Return type:

None