feat(track-a-source): ADR-013 leg 2b — Hop-A source adapter (Track-A archive → PredictionFrame)#101
Open
Polichinel wants to merge 1 commit into
Open
feat(track-a-source): ADR-013 leg 2b — Hop-A source adapter (Track-A archive → PredictionFrame)#101Polichinel wants to merge 1 commit into
Polichinel wants to merge 1 commit into
Conversation
…→ PredictionFrame) The consumer side of §3: read a Track-A archive, verify the shard bytes against the Hop-A manifest's declared sha256 (§3.2 — the verification this repo owns on read), check the §3.1 member triple, assert the payload matches the header's own declarations (sample_count, dtype, identifier lengths — the per-hop ingest assert), gate on contract major version (§2.1), and build the interior PredictionFrame via frames.build_prediction_frame. frames_for_target() assembles a (run, target) from its manifest — manifest content is identity (§3.3): listed shards must all be present, months must cover exactly expected_months, cell counts must match; a torn run is never assembled. Pandas-free by construction; mechanism guards only — the §6 policy gate (delivery.draws, S_min) stays at the FAO-facing upload. Tests use the §10 golden fixture as oracle: happy path from canonical bytes, tamper paths from surgically corrupted copies breaking exactly one declared fact each (hash, member set, S, dtype, major version, target, months, cell count, identifier length). MINOR header drift (1.9) accepted per §2.1. 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.
What
The consumer side of ADR-013 §3 (build-sequence leg 2b):
views_postprocessing/unfao/track_a_source.pyreads a Hop-A Track-A archive from the prediction store and produces the interiorPredictionFrame— verified, declared, fail-loud, pandas-free.Contract obligations discharged
read_shard(expected_sha256=…)y_pred.npy+identifiers.npz+metadata.json(N, sample_count), dtype, identifier lengths Nread_shard_require_contract_major(manifest + header)expected_months, cell counts match; a torn run is never assembledframes_for_targetNot here by design: the §6 no-collapse policy gate (
delivery/draws.py,s_min) runs at the FAO-facing upload (leg 2c), not at ingest — this module is mechanism guards only. Store I/O (Appwrite download) stays in the manager; this module takes bytes.Tests (15, golden fixture as oracle)
Happy path reads the canonical §10 fixture bytes; every tamper case starts from the real fixture and breaks exactly one declared fact — tampered bytes, missing member, header lying about
sample_count/dtype, identifier length mismatch, MAJOR bump (manifest and header), missing shard bytes, target disagreement, wrong month coverage, wrong cell count, missing manifest field. MINOR drift (1.9) explicitly accepted.Gates:
ruffclean, 168 passed / 44 xfailed.Refs: ADR-013 (
docs/ADRs/013_sampled_forecast_wire_contract.md), #45, #88. Next leg: 2c (sink adapter, #91).🤖 Generated with Claude Code