Repository navigation
fix(delivery): 255-safe provenance descriptions + loud upload port (#131 findings) - #132
Merged
Merged
Conversation
…riptions + loud upload port Run-0's historical upload stranded an orphan: the file uploaded but Appwrite rejected its metadata document (description attribute caps at 255 chars; the prose-prefixed C-15 provenance exceeded it), and the store module's graceful degradation only logged the error — the port's ledger then falsely claimed success. Two fixes: provenance.compact_description (delivery/, pipeline-core- free) emits compact JSON provenance guaranteed <=255 with fail-loud refusal to truncate, used by both historical description paths; _ContractStorePort.upload now inspects the OperationResult and RAISES on success=False — upstream graceful degradation must never silently strand our artifacts. Refs #131 (run-0 delivery verification). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 28, 2026
test(redaction): þing-01 P2 (#135) — delivery-log/provenance redaction audit + permanent guards
#136
Merged
Polichinel
added a commit
that referenced
this pull request
Jul 31, 2026
…onfig (#159) Closes #149 and #145; closes register C-63; resolves C-29. Epic #148. The frame-native contract path replaced the pandas path and won — run-0 delivered global-land 2026-07-27, FAO served since. The replaced path was kept behind a config fork "until run 0 proves the contract path live" (C-40) and never removed. D-11 warned that if it lingered the duplication would become permanent. This is the removal, not new work. Two independent axes (wire_contract, data_format) gave four delivery modes; production used one; omitting either key silently selected the retired half, because .get() returning None is indistinguishable from a deliberate False. That is the inference ADR-003 forbids, in the repo that authored it. unfao/managers/unfao.py 636 -> 406 lines 14 config forks -> 0, plus one refusal pandas / PGMDataset -> gone from the manager Deleted: the legacy _read_forecast_data body, _read_historical_data's pandas leg, _append_metadata, _delivery_description, _clip_observed_history, the legacy _save body (whose AppwriteConfig duplicated _unfao_appwrite_config verbatim), and LEGACY_FORECAST_FILTERS. _prod_forecasts_datastore lost its name_scoped parameter — it existed only for the caller that no longer exists (ISP). Added: unfao/launch_config.py — the launch declarations, asserted not inferred. Sibling of appwrite_env (that one validates the environment, this one the delivery mode), same fail-loud shape, dependency-light. A launcher that omits a key is refused BY NAME and told there is no fallback, so nobody "fixes" it by setting False. #145's silent uploads go with the legacy _save: the surviving path uploads only through _ContractStorePort, which already raises on a failed result — the guard written after run-0 stranded an invisible orphan (PR #132). Tests: test_selection_guard.py rewritten to pin the RETIREMENT rather than a golden string for deleted code, re-pointed at ADR-013's post-adoption record so the disjointness fact stays checkable, and asserting the Hop-B clause still binds — retiring our reader must not read as relaxing the consumer's obligation. test_append_metadata.py deleted (it characterised a deleted method; its docstring said "keep in lockstep with _append_metadata"). test_launch_config.py added. Docstring maps in test_input_integrity_e2e.py corrected to the post-#149 tree. ADR-013: dated post-adoption entry recording the Hop-A retirement, the retired filter values, and that §11.4's Hop-B clause is untouched. Review findings addressed in-commit (/review-diff verdict was HOLD): - launch_config raised without logging — ADR-008:48 requires both. Fixed, with tests asserting the log, not just the raise. - _transform annotated -> list while returning None. Fixed. - the declaration check ran after _initialize_data_loader; a refused config paid for loader construction. Reordered. Registered C-71: appwrite_env has the identical ADR-008 gap (pre-existing, #134). Left for scope discipline — the module this one mirrors is now inconsistent with it, which is worth tracking rather than silently widening S1. Wire contract untouched: no file under wire/, delivery/ or fixtures/ in the diff. ruff clean; 303 passed, 41 xfailed, 5 known local pyarrow byte-parity failures (CI authoritative). Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Run-0 verification (#131) found the historical upload stranded as an orphan file: bytes in the bucket, metadata document rejected (
description> 255 chars — the C-15 prose prefix), error only logged by the store's graceful degradation, port ledger falsely green.delivery/provenance.compact_description: compact JSON provenance guaranteed ≤255, fail-loud (never truncate silently); both description paths use it; pipeline-core-free and unit-tested._ContractStorePort.uploadnow raises onsuccess=False— upstream graceful degradation can't silently strand our artifacts again.A rerun after this merge heals the gap: dedup is document-keyed, so the orphan (no document) won't block a fresh historical upload. 🤖 Generated with Claude Code