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.
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.pydocuments and raisesSystemExitfrom library helper_import_file_to_polarsafter catchingValueError;src/histdatacom/__init__.pymutatessys.modules[__name__].__class__to make the package module callable throughAPICaller;HistDataOperationError/ErrorCategorytaxonomy, 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:
sys.exit, raiseSystemExit, or terminate the interpreter for recoverable input/data/runtime failures;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:
HandoffBundleV1discovery/read/verify;No operation may require repository-relative files or an argparse namespace.
Exception contract
Create or extend a stable exception/result taxonomy covering at least:
Scientific
unsupported/refusedis 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: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:
histdatacomhas no destructive/process-exit side effect;SystemExit;sys.modulesclass is not required by the consumer;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.