Skip to content

Commit 70e5897

Browse files
mmckyclaude
andcommitted
P1 pilot: add lingcod_msy_recovery.csv with its manifest
The first dataset to land in the published tree, and the first manifest written against the schema sketch. Consumed by lecture-python-intro's msy_fishery lecture, which currently reads it from a relative path — so the downloaded notebook cannot resolve it. The repoint is the paired lecture PR. Licence established before adding, per AGENTS.md: RAM Legacy is CC BY 4.0, attribution-only, so rehosting this extract is permitted. Worth recording how that was found — ramlegacy.org states no licence at all; the authority is the Zenodo record behind its DOI (license id "cc-by-4.0", access_right "open"). Meeting a real file changed the schema in three ways, all folded back into manifest-schema.yml: - integrity splits into `migration` and `upstream`. Lingcod is a byte-perfect copy of what the lecture consumes, yet its upstream provenance cannot be re-derived at all. One "verified" field would have to overstate or understate it; two fields tell the truth. - `builder_status` records `unrecovered`. This file is constructed but ships no builder — the bug AGENTS.md names. The tempting fix is to relabel it verbatim, which buries the gap; instead it is now visible in the catalog. - `known_nulls` declares nulls that are correct. F/Fmsy is null in the terminal assessment year, which a blanket no-nulls validation rule would wrongly reject. Part of QuantEcon/meta#338 See QuantEcon/meta#336 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent aa66535 commit 70e5897

3 files changed

Lines changed: 236 additions & 8 deletions

File tree

lectures/lingcod_msy_recovery.csv

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
year,B_over_Bmsy,F_over_Fmsy
2+
1928,3.859289617,0.12815534
3+
1929,3.842213115,0.177669903
4+
1930,3.825136612,0.198058252
5+
1931,3.790983607,0.19223301
6+
1932,3.756830601,0.142718447
7+
1933,3.756830601,0.224271845
8+
1934,3.705601093,0.14368932
9+
1935,3.705601093,0.170873786
10+
1936,3.671448087,0.133009709
11+
1937,3.671448087,0.173786408
12+
1938,3.654371585,0.146601942
13+
1939,3.637295082,0.127184466
14+
1940,3.637295082,0.145631068
15+
1941,3.637295082,0.117475728
16+
1942,3.637295082,0.067961165
17+
1943,3.654371585,0.131067961
18+
1944,3.654371585,0.132038835
19+
1945,3.654371585,0.130097087
20+
1946,3.637295082,0.216504854
21+
1947,3.603142077,0.430097087
22+
1948,3.50068306,0.462135922
23+
1949,3.398224044,0.413592233
24+
1950,3.31284153,0.45631068
25+
1951,3.227459016,0.453398058
26+
1952,3.142076503,0.350485437
27+
1953,3.090846995,0.246601942
28+
1954,3.073770492,0.290291262
29+
1955,3.056693989,0.308737864
30+
1956,3.039617486,0.355339806
31+
1957,3.005464481,0.526213592
32+
1958,2.920081967,0.539805825
33+
1959,2.851775956,0.466990291
34+
1960,2.800546448,0.417475728
35+
1961,2.74931694,0.449514563
36+
1962,2.698087432,0.386407767
37+
1963,2.663934426,0.391262136
38+
1964,2.629781421,0.340776699
39+
1965,2.612704918,0.413592233
40+
1966,2.578551913,0.518446602
41+
1967,2.527322404,0.57961165
42+
1968,2.476092896,0.612621359
43+
1969,2.407786885,0.575728155
44+
1970,2.339480874,0.850485437
45+
1971,2.237021858,1.077669903
46+
1972,2.117486339,1.563106796
47+
1973,1.929644809,1.766990291
48+
1974,1.741803279,1.951456311
49+
1975,1.572745902,1.951456311
50+
1976,1.449795082,2.077669903
51+
1977,1.321721311,1.485436893
52+
1978,1.270491803,1.941747573
53+
1979,1.166325137,2.718446602
54+
1980,1.00068306,3.378640777
55+
1981,0.840163934,3.378640777
56+
1982,0.712090164,3.504854369
57+
1983,0.594262295,2.67961165
58+
1984,0.544740437,2.805825243
59+
1985,0.488387978,3.951456311
60+
1986,0.403005464,3.854368932
61+
1987,0.37568306,4.019417476
62+
1988,0.37397541,4.310679612
63+
1989,0.358606557,4.834951456
64+
1990,0.3125,4.553398058
65+
1991,0.285177596,4.32038835
66+
1992,0.268101093,4.174757282
67+
1993,0.256147541,3.485436893
68+
1994,0.266393443,2.27184466
69+
1995,0.315915301,2.019417476
70+
1996,0.365437158,2.038834951
71+
1997,0.396174863,1.815533981
72+
1998,0.425204918,1.300970874
73+
1999,0.479849727,1.398058252
74+
2000,0.539617486,0.63592233
75+
2001,0.650614754,0.49223301
76+
2002,0.800887978,1.029126214
77+
2003,0.988729508,1.291262136
78+
2004,1.243169399,0.195145631
79+
2005,1.656420765,0.261165049
80+
2006,2.083333333,0.249514563
81+
2007,2.510245902,0.144660194
82+
2008,2.885928962,0.093203883
83+
2009,3.193306011,
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Manifest for lingcod_msy_recovery.csv — the first manifest written against
2+
# the schema sketched in ../manifest-schema.yml (PLAN Phase 8, pilot P1).
3+
4+
filename: lingcod_msy_recovery.csv
5+
title: Pacific Coast lingcod — biomass and fishing pressure relative to MSY
6+
description: >
7+
Annual B/Bmsy and F/Fmsy for the U.S. Pacific Coast lingcod (Ophiodon
8+
elongatus) fishery, 1928-2009. Illustrates a stock fished below its MSY
9+
reference points and subsequently rebuilt.
10+
11+
# Constructed, not verbatim: these are two ratio series for a single stock,
12+
# subset out of a database that ships as a multi-table release. Selecting the
13+
# stock and the columns is our processing, so the class is `constructed` — and
14+
# a constructed dataset is supposed to ship its builder. This one does not.
15+
# See `builder` below.
16+
class: constructed
17+
18+
source:
19+
name: RAM Legacy Stock Assessment Database
20+
url: https://www.ramlegacy.org/
21+
doi: 10.5281/zenodo.14043031
22+
version: v4.66-assessment-only # current upstream release; NOT known to be
23+
# the release this extract was taken from
24+
citation: >
25+
Ricard, D., Minto, C., Jensen, O. P., & Baum, J. K. (2012). Evaluating the
26+
knowledge base and status of commercially exploited marine species with the
27+
RAM Legacy Stock Assessment Database. Fish and Fisheries, 13(4), 380-398.
28+
29+
license:
30+
name: CC BY 4.0
31+
url: https://creativecommons.org/licenses/by/4.0/
32+
redistribution: permitted
33+
verified: 2026-07-16
34+
# Established against the Zenodo record for v4.66, which reports license id
35+
# "cc-by-4.0" and access_right "open". Not stated on ramlegacy.org itself --
36+
# the homepage gives only the citation, so the Zenodo record is the
37+
# authority. Attribution is the sole condition and the citation above
38+
# carries it, so rehosting this extract is permitted.
39+
40+
retrieved: null # unrecorded -- see integrity.upstream
41+
maintainer: QuantEcon
42+
43+
# ---------------------------------------------------------------------------
44+
# Integrity (PLAN Phase 7)
45+
# ---------------------------------------------------------------------------
46+
# Two independent questions with different answers here, which is why they are
47+
# recorded separately rather than as one status field:
48+
# migration -- does this match what the lecture consumed before the repoint?
49+
# upstream -- is this actually what RAM Legacy says?
50+
# A file can be a perfect copy of a lecture's data and still have unprovable
51+
# provenance. Collapsing both into one "verified" would overstate this file.
52+
53+
integrity:
54+
sha256: fc2f873f97a9b7c6d335ca88203c321b4451cf4b94feb16ca40e99551c49c092
55+
56+
migration:
57+
status: verified
58+
date: 2026-07-16
59+
method: >
60+
sha256 byte-compare against lecture-python-intro's copy at
61+
lectures/datasets/lingcod_msy_recovery.csv, immediately before the
62+
repoint. Identical, so the repoint cannot change lecture output.
63+
64+
upstream:
65+
status: unverifiable
66+
date: 2026-07-16
67+
method: >
68+
Cannot be re-derived. The extract does not record which RAM Legacy stock
69+
id it came from, which database version, or what transformation produced
70+
the two ratio columns, and no builder was committed with it. Verifying
71+
would mean re-identifying the stock in a current release and confirming
72+
the series match -- possible in principle, not done. Treat the values as
73+
trusted-by-provenance-of-the-author, not as independently checked.
74+
75+
# ---------------------------------------------------------------------------
76+
# Shape
77+
# ---------------------------------------------------------------------------
78+
79+
schema:
80+
format: csv
81+
columns:
82+
- {name: year, dtype: int64, description: calendar year}
83+
- {name: B_over_Bmsy, dtype: float64, description: stock biomass relative to the biomass supporting MSY}
84+
- {name: F_over_Fmsy, dtype: float64, description: fishing pressure relative to the pressure achieving MSY}
85+
row_count_floor: 82
86+
date_range: {start: 1928, end: 2009}
87+
# F_over_Fmsy is null in the terminal year (2009) -- expected, and normal for
88+
# a terminal assessment year. Recorded so PR validation does not "fix" it:
89+
# a blanket no-nulls rule would reject this file wrongly.
90+
known_nulls:
91+
F_over_Fmsy: 1
92+
93+
# ---------------------------------------------------------------------------
94+
# Consumers -- how a correction knows what to rebuild
95+
# ---------------------------------------------------------------------------
96+
97+
consumers:
98+
- repo: QuantEcon/lecture-python-intro
99+
file: lectures/msy_fishery.md
100+
101+
# ---------------------------------------------------------------------------
102+
# Builder
103+
# ---------------------------------------------------------------------------
104+
# AGENTS.md: "A constructed dataset without its committed builder is a bug."
105+
# This file is that bug, inherited rather than introduced -- it is one of the
106+
# constructed-but-unscripted set PLAN Phase 9 tracks. Recorded explicitly
107+
# instead of being quietly misclassified as verbatim, so the gap is visible in
108+
# the generated catalog rather than lost.
109+
110+
builder: null
111+
builder_status: unrecovered # unrecovered | committed | not-applicable

manifest-schema.yml

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,45 @@ license:
5353
# Redistribution must be confirmed before a file is served from this repo —
5454
# unlicensed rehosting is a blocker, not a nice-to-have (AGENTS.md).
5555
redistribution: permitted
56+
verified: 2026-07-16 # when, and against what, this was
57+
# established — a licence claim with no
58+
# date is not evidence. P1 found the
59+
# authority is often not the project
60+
# homepage but its Zenodo/DOI record.
5661

5762
retrieved: 2024-04-10 # ISO date the bytes were obtained
5863
maintainer: QuantEcon # who fixes this when it breaks
5964

6065
# ---------------------------------------------------------------------------
6166
# Integrity (PLAN Phase 7) — a file is not promoted with unknown status
6267
# ---------------------------------------------------------------------------
68+
# Two independent questions, and P1 (lingcod) proved they get different answers:
69+
# that file is a byte-perfect copy of what the lecture consumed, while its
70+
# upstream provenance cannot be re-derived at all. One combined "verified" field
71+
# would have had to either overstate or understate it, so they are split.
6372

6473
integrity:
6574
sha256: null # of the committed file
66-
verified: null # ISO date of the last check
67-
method: >
68-
How this was checked: re-fetch-and-compare for verbatim; re-run the builder
69-
and compare the overlap window for constructed/dynamic; spot-check against
70-
the cited publication for author-assembled. Say so plainly when full
71-
verification is not possible.
72-
status: unverified # verified | spot-checked | unverified | failing
75+
76+
# Does this match what the consuming lecture used before the repoint?
77+
# Guards the migration: a mismatch means repointing silently changes output.
78+
# Hard prerequisite for Phase 8.
79+
migration:
80+
status: unverified # verified | unverified | failing | not-applicable
81+
date: null
82+
method: null # e.g. sha256 compare against <repo>'s copy
83+
84+
# Is this actually what the upstream source says?
85+
# Guards the provenance claim above.
86+
upstream:
87+
status: unverified # verified | spot-checked | unverifiable | unverified | failing
88+
date: null
89+
method: >
90+
re-fetch-and-compare for verbatim; re-run the builder and compare the
91+
overlap window for constructed/dynamic; spot-check against the cited
92+
publication for author-assembled. Say so plainly when verification is
93+
impossible — `unverifiable` with a reason is an honest answer and is
94+
what the catalog should show. Silence is not.
7395
7496
# ---------------------------------------------------------------------------
7597
# Shape — what a consumer can rely on; also the basis for PR validation tests
@@ -84,6 +106,12 @@ schema:
84106
row_count_floor: 5 # PR validation fails below this
85107
date_range: {start: 1960, end: null} # null end = tracks the moving source
86108

109+
# Nulls that are correct and must not fail validation. P1 found a real one:
110+
# lingcod's F/Fmsy is null in its terminal assessment year, which a blanket
111+
# no-nulls rule would reject. Declaring them makes the invariant tests
112+
# (Phase 5) enforceable without hand-waving.
113+
known_nulls: {} # e.g. {F_over_Fmsy: 1}
114+
87115
# ---------------------------------------------------------------------------
88116
# Consumers — machine-readable, so a correction knows what to rebuild
89117
# ---------------------------------------------------------------------------
@@ -100,7 +128,13 @@ consumers: []
100128
# Builder — required for constructed and dynamic-snapshot; omit for verbatim
101129
# ---------------------------------------------------------------------------
102130

103-
builder: scripts/business_cycle.py
131+
builder: scripts/business_cycle.py # path to the committed builder, or null
132+
133+
# AGENTS.md says a constructed dataset without its builder is a bug — but the
134+
# repo has inherited several (PLAN Phase 9), and P1's own pilot file is one.
135+
# The tempting workaround is to misclassify them as `verbatim`, which buries
136+
# the gap. This field keeps it visible in the generated catalog instead.
137+
builder_status: committed # committed | unrecovered | not-applicable
104138

105139
# Dynamic snapshots only. Drives the scheduled refresh-as-PR (PLAN Phase 5).
106140
cadence: annual # e.g. daily | weekly | monthly | annual

0 commit comments

Comments
 (0)