Skip to content

design(v2.10): freeze a stable downstream consumer facade and separate library errors from CLI/process exits #723

Description

@dmidlo

Parent handoff milestone: #721
Related: #513 #526 #612 #632#641 #722

Audit finding

The current public package still carries legacy API/process coupling that is acceptable for backwards compatibility but unsafe as the implicit contract for the forthcoming private ML consumer.

Concrete live-code examples on main:

  • src/histdatacom/api.py documents and raises SystemExit from library helper _import_file_to_polars after catching ValueError;
  • src/histdatacom/__init__.py mutates sys.modules[__name__].__class__ to make the package module callable through APICaller;
  • the repository already has a structured HistDataOperationError/ErrorCategory taxonomy, but legacy library paths do not consistently use it.

A clean downstream consumer must not unexpectedly terminate its process because an imported library operation encountered invalid data, and it must not depend on module-class mutation or CLI-only side effects to access scientific products.

Outcome

Freeze one explicit, typed, versioned consumer facade for dataset/handoff discovery, verification, projection and bounded replay. The facade is the supported Python-library boundary for #721 and is independently usable from the CLI.

Legacy callable-module and convenience APIs may remain during a deprecation window, but the handoff consumer must not require them.

Library/CLI separation

Library functions must:

  • return typed values/receipts or raise documented typed exceptions;
  • never call sys.exit, raise SystemExit, or terminate the interpreter for recoverable input/data/runtime failures;
  • distinguish scientific refusal/unsupported state from configuration, dependency, network, filesystem, parse, validation, cancellation and unknown programming/runtime failures;
  • preserve original exception chaining and stable machine-readable reason codes;
  • avoid printing/progress/UI side effects unless explicitly supplied an observer/progress sink.

CLI adapters may map typed exceptions/receipts to exit codes, human-readable messages and progress output at the outermost process boundary.

Consumer facade scope

At minimum expose supported operations for:

  • package/schema/handoff compatibility inspection;
  • HandoffBundleV1 discovery/read/verify;
  • dataset/view/feature-registry discovery;
  • deterministic feature projection;
  • canonical split/evidence-unit/weight retrieval;
  • origin/uncertainty/missingness/availability inspection;
  • lineage ancestry queries;
  • bounded golden-sample replay/verification;
  • explicit refusal for unsupported origin/information/right/schema modes.

No operation may require repository-relative files or an argparse namespace.

Exception contract

Create or extend a stable exception/result taxonomy covering at least:

  • invalid consumer request;
  • incompatible schema/package/handoff;
  • missing required artifact;
  • artifact integrity failure;
  • unsupported information/origin mode;
  • rights/policy refusal;
  • causal/lineage verification failure;
  • resource/preflight refusal;
  • dependency/runtime failure;
  • unexpected internal error.

Scientific unsupported/refused is not interchangeable with operational/runtime failure. A broad catch may translate an exception only at a documented boundary and must retain the original class/cause in diagnostic evidence.

Legacy compatibility

Inventory public legacy entry points including callable-module behavior, Api, CLI-oriented helpers and import-time compatibility shims. Classify each as:

  • supported consumer API;
  • compatibility-only/deprecated;
  • CLI-only;
  • internal/private.

Do not remove legacy behavior merely to satisfy this issue unless SemVer/deprecation policy permits it. The requirement is that new consumers have a conventional supported alternative and that legacy quirks cannot leak into the handoff contract.

Tests

A clean external test package must prove:

  • importing histdatacom has no destructive/process-exit side effect;
  • invalid library input raises a typed exception rather than SystemExit;
  • the same failure maps to a stable CLI exit code only in CLI execution;
  • consumer operations work without calling the module object;
  • monkeypatching/replacing sys.modules class is not required by the consumer;
  • structured scientific refusal remains distinct from unexpected exception;
  • exception serialization/redaction does not expose credentials/secrets;
  • public facade signatures and reason-code schemas are captured in compatibility fixtures.

Acceptance

#721's clean-room consumer uses only this supported facade plus published artifacts; no consumer path relies on package-call masquerading, argparse/process globals, SystemExit, repository-local state or undocumented side effects; CLI and Python-library semantics are independently testable; and #632 compatibility policy governs future facade evolution.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestmodern-toolingModern tooling, CI, release, coverage, and packaging hygienescientific-validationFalsifiability, calibration, leakage, reproducibility, and scientific acceptance gates

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions