Skip to content

fix(delivery): C-79 and C-83 — two refusals on the live FAO path - #222

Merged
Polichinel merged 1 commit into
developmentfrom
fix/c79-c83-delivery-refusals
Aug 5, 2026
Merged

fix(delivery): C-79 and C-83 — two refusals on the live FAO path#222
Polichinel merged 1 commit into
developmentfrom
fix/c79-c83-delivery-refusals

Conversation

@Polichinel

Copy link
Copy Markdown
Collaborator

B4. Both Tier 2, both on the path that delivers to FAO.

C-79 — the store port failed open, and had zero tests

The comment beside _ContractStorePort.upload's result check calls it "the whole mechanism". It is: pipeline-core's store, on a metadata failure after the file is uploaded, logs and returns success=False rather than raising. A caller that discards the result ships a file with no metadata document — invisible to the consumer rather than absent. That is what happened to run-0's historical artifact on 2026-07-27.

The check was if success is False. A result that was None, or lacked the attribute, or carried a non-bool, sailed straight through as though the upload had worked. Now is not True. The dead to_dict() fallback went with it — an unrecognised result should be refused and named, not adapted to silently. The message reports what it actually received, because success=None (a moved contract) and success=False (a reported failure) send an operator to different places.

tests/test_store_port.py — 16 tests over both partners, where there were none. The standing excuse for source-scanning manager-side facts is that the managers need Appwrite env and a views-models path manager to instantiate. The port needs neither: it takes a store object and calls four methods on it. A fake store was always enough; nobody had tried.

Its trigger fired two days ago and nobody noticed. The entry read "the 3.0.0 bump is the next occasion". The bump landed 2026-08-03, C-44 closed on a wheel-level verification of the suite, and the return contract was never re-read. test_register_integrity.py cannot catch that — its ten checks are structural, and none asks whether a named external event has occurred. That gap is C-82's.

C-83 — a failed import reported as a wrong declaration

get_queryset() returns None for any exception while importing config_queryset.py. declared_data_format(None) defaults to 'dataframe'. The format guard then says:

the queryset declares data_format='dataframe' … Set data_format: 'feature_frame' in the postprocessor's config_queryset

…pointing at a file that already says exactly that, while someone is fixing a failed run.

launch_config.assert_queryset_was_importable now runs first, and both managers read the queryset once and reuse the value. The refusal says what happened and steers away from the config file — "This is NOT a declaration problem: do not edit data_format until the module imports" — toward the traceback pipeline-core logged, and toward a missing sibling checkout or dependency. It logs before it raises (ADR-008).

Three guards, because order is the fix. The refusal fires and names the real fault; an importable queryset passes (the format question belongs to the next check, and separating them is the whole point); and per partner, get_queryset() is called exactly once with importability checked first.

Not fixed here, deliberately: upstream still returns None for any import exception, so the ambiguity survives at its source. We stopped passing it into a function whose contract is to default. Raising upstream would be better and is not ours to do — and waiting would have left the misleading message on the live path meanwhile.

Verification

Mutation-proven three ways: revert the polarity (4 tests fail), delete the importability check (1 fails), reverse the order (1 fails).

352 passed / 40 xfailed / 0 failed
ruff check .  ->  All checks passed!

Register 83 / 12 open / 71 resolved.

C-79: the store port failed OPEN, and had zero tests
The comment beside `_ContractStorePort.upload`'s result check calls it "the whole
mechanism". It is: pipeline-core's store, on a metadata failure AFTER the file is
uploaded, logs and RETURNS success=False rather than raising, so a caller that discards
the result ships a file with no metadata document -- invisible to the consumer. That
happened to run-0's historical artifact on 2026-07-27.

The check was `if success is False`. A result that was None, or lacked the attribute, or
carried a non-bool, sailed through as though the upload had worked. Now `is not True`.
The dead to_dict() fallback went with it: an unrecognised result should be refused and
named, not adapted to silently. The message reports what it actually received, because
success=None (a moved contract) and success=False (a reported failure) send an operator
to different places.

tests/test_store_port.py -- 16 tests over both partners, where there were none. The
standing excuse for source-scanning manager facts is that managers need Appwrite env and
a views-models path manager; the port needs neither, so it never applied here.

Its trigger fired on 2026-08-03 and nobody noticed. The entry read "the 3.0.0 bump is
the next occasion"; the bump landed, C-44 closed on a wheel-level suite verification,
and the return contract was never re-read. test_register_integrity cannot catch that --
its checks are structural and none asks whether a named external event has occurred.

C-83: a failed import reported as a wrong declaration
get_queryset() returns None for ANY exception importing config_queryset.py;
declared_data_format(None) defaults to 'dataframe'; the format guard then tells the
operator to set data_format: 'feature_frame' in a file that already says exactly that.

launch_config.assert_queryset_was_importable now runs FIRST, and both managers read the
queryset once and reuse it. The refusal says what happened and steers away from the
config file -- "This is NOT a declaration problem: do not edit data_format until the
module imports" -- toward the traceback pipeline-core logged. Logs before it raises.

Three guards, because order IS the fix: the refusal fires and names the real fault; an
importable queryset passes (the format question belongs to the next check); and per
partner, get_queryset() is called exactly once with importability checked first.

Not fixed here, deliberately: upstream still returns None for any import exception. We
stopped passing it into a function whose contract is to default. Raising upstream would
be better and is not ours; waiting for it would have left the misleading message on the
live FAO path meanwhile.

Mutation-proven three ways -- revert the polarity (4 fail), delete the importability
check (1 fails), reverse the order (1 fails).

352 passed / 40 xfailed / 0 failed. ruff clean. Register 83/12/71.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Polichinel
Polichinel merged commit 11ea673 into development Aug 5, 2026
4 checks passed
@Polichinel
Polichinel deleted the fix/c79-c83-delivery-refusals branch August 5, 2026 05:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant