# Memory.md — Trạng thái làm việc Dr_GCM

## Snapshot tiếp tục ngày 2026-10-17

- Audit chỉ đọc khoảng 07:55 ICT xác nhận baseline monitor PID `12105`, downloader PID `11530`, monthly worker PID `14729` và soil-moisture monitor PID `17671` đều còn hoạt động đúng thiết kế. Chỉ có một Python CDS worker (PID `30541`), đang xử lý init `2006-09`; không có recovery worker và không có file `.part` tại thời điểm kiểm tra.
- Số tệp hoàn chỉnh được status script ghi nhận: 303/480 instantaneous, 308/480 accumulated và 98/480 monthly. Init `2006-08` hoàn tất lúc 07:32 ICT; monthly worker vẫn chờ đúng instantaneous gap `1989-03`.
- Request `2006-09` đã được CDS chấp nhận và chuyển sang running, sau đó gặp `RemoteDisconnected`; CDS client đang tự retry sau 120 giây. Process còn tồn tại và baseline monitor heartbeat đều mỗi 300 giây, nên chưa có bằng chứng lỗi vĩnh viễn hoặc cần can thiệp.
- Năm gap damaged-tape vẫn là `1989-03`, `1990-03`, `1991-01`, `1991-03`, `1992-04`; recovery `1989-03` vẫn `blocked_external` tại `stl1` lead 750 h. Chưa đạt tiêu chí hoàn tất download hoặc inventory strict.
- Soil-moisture monitor chưa gửi request và tiếp tục chờ baseline monitor hoàn tất, đúng quy tắc dùng chung một global CDS lock. Hiện có 0 tệp soil moisture.
- Dung lượng: `data/ecmwf/raw_split` khoảng 282 GiB, `data/ecmwf/monthly` khoảng 1.9 GiB; filesystem `/work` còn khoảng 31 TiB. Repository vẫn không có Git metadata. Lượt này không khởi động/dừng job, không sửa mã/cấu hình/dữ liệu và không chạy test suite vì chỉ audit trạng thái.

## Quyết định và trạng thái soil moisture ngày 2026-10-15

- Người dùng cung cấp request CDS đúng cho `seasonal-original-single-levels`, ECMWF System 51: tên catalogue `volumetric_soil_moisture`, daily lead 24-hour và có thể bao phủ tới biên LT=7. Các pilot cũ dùng `volumetric_soil_water_layer_1` không còn được xem là bằng chứng biến không tồn tại.
- Đã cập nhật cấu hình để kỳ vọng NetCDF `vsw`, 25 members và bốn `soilLayer`; chưa gán độ sâu lớp hoặc temporal semantics trước khi xem metadata file thật.
- Người dùng duyệt: chạy pilot trước, nếu đạt thì tự động tải toàn bộ soil moisture 1981-01..2020-12 ở background và tự monitor.
- Ước tính trước khi chạy: khoảng 0.4 GB/tháng chưa nén, toàn kỳ khoảng 50–200 GB tùy compression; nhiều ngày đến vài tuần với một worker; `/work` còn khoảng 29 TB tại audit gần nhất.
- Đã thêm `scripts/download_ecmwf_soil_moisture.sh`, `scripts/soil_moisture_monitor.sh`, `scripts/soil_moisture_status.sh`. Workflow dùng cùng global CDS lock, pilot 2005-01 và 1981-01 với lead 24/48/72, chỉ tải toàn kỳ nếu cả hai validator đạt, resume theo tháng và atomic promotion.
- Monitor bản cuối detached PID/PGID/SID `17671` khởi động lại lúc 17:12 ICT sau khi nạp bản có cooldown, hiện chờ baseline monitor PID `12105`; chưa gửi request soil moisture và không tăng concurrency. Process group monitor cũ `15001` đã được kết thúc riêng, downloader baseline PGID `11530` và monitor baseline PGID `12105` không bị tác động. Kiểm tra bằng `bash scripts/soil_moisture_status.sh`.
- JSON, `bash -n`, dry-run pilot/full đạt; test mục tiêu downloader/pilot `14 passed in 2.24s`; full suite cuối cùng `71 passed in 24.44s`. Pilot lỗi được retry theo cooldown 24 giờ, không tạo request storm.

## Quyết định xác nhận ngày 2026-10-14

- Người dùng xác nhận dữ liệu phía mô hình phải là reforecast/hindcast của các GCM; không sử dụng reanalysis.
- ERA5, ERA5-Land và các reanalysis khác không được dùng làm predictor, nguồn thay thế hoặc ghép bù cho chuỗi GCM.
- Soil moisture vẫn là predictor bắt buộc. Nếu ECMWF System 51 không có hindcast 1981–2020 đồng nhất, chỉ xem xét nguồn GCM reforecast khác và phải trình người dùng duyệt trước khi huấn luyện.

## Snapshot tiếp tục ngày 2026-10-12

- Audit chỉ đọc lúc 08:01 ICT xác nhận monitor PID `12105`, downloader PID `11530` và monthly worker PID `14729` vẫn detached, hoạt động đúng thiết kế. Chỉ có một Python CDS worker (PID `10037`), đang request init `1997-05`; không có recovery worker và không có file `.part` tại thời điểm kiểm tra.
- Tiến độ đã xác minh: 191/480 instantaneous, 196/480 accumulated và 98/480 monthly. Hai nhóm raw đều đã hoàn tất đến `1997-04`; monthly worker vẫn chờ đúng gap instantaneous `1989-03`. Năm gap damaged-tape vẫn là `1989-03`, `1990-03`, `1991-01`, `1991-03`, `1992-04`; chưa đạt tiêu chí hoàn tất download/inventory strict.
- Request `1997-05` được CDS chấp nhận và chuyển sang running; log sau đó ghi một `RemoteDisconnected` và client tự retry sau 120 giây. Process vẫn tồn tại sau hơn 36 phút, monitor heartbeat đều mỗi 300 giây; chưa có bằng chứng lỗi vĩnh viễn hoặc cần can thiệp.
- Dung lượng: `data/ecmwf/raw_split` khoảng 179 GiB, `data/ecmwf/monthly` khoảng 1.9 GiB; `/work` còn khoảng 30 TiB. Hai observation symlink và mask chính thức đều truy cập được. Repository vẫn không có Git metadata. Lượt này không sửa mã, không restart/kill job và không chạy test suite vì chỉ audit trạng thái.

## Snapshot tiếp tục ngày 2026-10-11

- Audit chỉ đọc khoảng 11:10 ICT xác nhận monitor PID `12105`, downloader PID `11530` và monthly worker PID `14729` vẫn detached, hoạt động đúng thiết kế. Chỉ có một Python CDS worker (PID `12383`), đang request init `1995-05`; không có recovery worker và không có file `.part` tại thời điểm kiểm tra.
- Bản vá fallback HTTP 403 đã được xác minh trên dữ liệu thật: `1993-07 accumulated` được tạo lúc 17:34 ICT ngày 2026-10-10, manifest ghi `downloaded_split_fallback` do URL object-store cache ngày 2026-10-04 trả 403. File merge cuối có 237,973,221 bytes và validator độc lập đạt đủ 5 biến (`slhf`, `sshf`, `tp`, `tsr`, `ttr`), 25 members, 215 lead từ 24 đến 5160 h. File instantaneous cùng tháng cũng đạt đủ 4 biến, 25 members, 860 lead từ 6 đến 5160 h. Downloader sau đó tiếp tục bình thường qua `1995-04`; lỗi cache-expiry `1993-07` được xem là đã giải quyết.
- Tiến độ đã xác minh: 167/480 instantaneous, 172/480 accumulated và 98/480 monthly. Năm gap damaged-tape vẫn là `1989-03`, `1990-03`, `1991-01`, `1991-03`, `1992-04`; monthly worker tiếp tục chờ đúng tại `1989-03`, nên chưa đạt tiêu chí hoàn tất download/inventory strict.
- Dung lượng: `data/ecmwf/raw_split` khoảng 156 GiB, `data/ecmwf/monthly` khoảng 1.9 GiB; `/work` còn khoảng 30 TiB. Repository vẫn không có Git metadata. Lượt này không sửa mã, không restart/kill job và không chạy test suite vì chỉ audit trạng thái.

## Snapshot tiếp tục ngày 2026-10-10

- Handoff trước khi người dùng logout lúc 17:00 ICT: monitor PID `12105`, downloader PID `11530` và monthly worker PID `14729` đều detached với `PPID=1`, PGID/SID riêng; heartbeat monitor đều mỗi 300 giây đến 16:58. Đúng một downloader worker giữ lock, nên logout không làm dừng job. Monitor sẽ tự restart downloader từ tháng bắt buộc đầu tiên nếu lock mất, giữ concurrency=1, rồi recovery các gap tuần tự sau khi dải chính hoàn tất.
- Không khởi động `baseline_watchdog.sh` cũ: script đó tìm raw gap đầu tiên từ 1981-01 nhưng không áp dụng ledger deferred/cooldown, nên có thể xung đột với monitor hiện hành tại `1989-03`. Nguồn kiểm soát duy nhất là `baseline_download_monitor.sh`; status/log lần lượt qua `scripts/baseline_download_monitor_status.sh` và `outputs/logs/ecmwf_baseline_monitor.log`.
- Audit chỉ đọc khoảng 15:20 ICT: monitor PID 12105 và monthly worker PID 14729 còn hoạt động; không có recovery worker. Tiến độ là 146/480 instantaneous, 150/480 accumulated và 98/480 monthly; năm gap damaged-tape đã biết vẫn là 1989-03, 1990-03, 1991-01, 1991-03 và 1992-04.
- Dải chính bị giữ tại accumulated `1993-07`: CDS liên tục báo request thành công nhưng trả cùng artifact cache tạo ngày 2026-10-04, URL object-store trả HTTP 403. Đây không phải damaged-tape; instantaneous 1993-07 đã hợp lệ (721,048,928 bytes, 25 members, 860 lead 6..5160 h).
- `download_format=unarchived` không phá được cache lỗi: các retry 15:48, 16:18 và 16:48 đều có request ID mới nhưng CDS vẫn trả đúng URL artifact ngày 2026-10-04 và HTTP 403. Đã bổ sung fallback chỉ cho 403 từ object-store: request tuần tự từng biến trong cùng group, checkpoint/validate từng mảnh, merge, validate toàn group rồi atomic-promote; 403 khác không kích hoạt fallback. Test mục tiêu đạt `10 passed in 1.57s`, full suite đạt `69 passed in 17.75s`, `py_compile` đạt. Vẫn cần xác minh retry tự động kế tiếp thực sự tải/promote accumulated 1993-07 trước khi coi lỗi đã giải quyết.
- Dung lượng tại snapshot: raw split khoảng 137 GiB, monthly 1.9 GiB, `/work` còn khoảng 30 TiB. Repository vẫn không có Git metadata.
- Retry tự động kế tiếp của 1993-07 dự kiến khoảng 17:18 ICT ngày 2026-10-10; process Python mới sẽ tự nạp fallback vừa sửa. Không restart/kill worker để ép retry; sau mốc này kiểm tra manifest, các split-part và file accumulated 1993-07.

## Cập nhật gần nhất

- Thời điểm: 2026-10-11 11:10 ICT (Asia/Ho_Chi_Minh).
- Mục tiêu hiện tại: downloader một worker tiếp tục từ `1995-05` đến 2020-12 dưới monitor tự phục hồi; sau khi dải chính hoàn tất/deferred, monitor tự phục hồi tuần tự mọi gap damaged-tape trước khi coi download hoàn tất. Fallback cache-expiry đã được xác minh thành công trên `1993-07`.

## Quyết định đã được xác nhận từ yêu cầu hiện hành

- GCM giai đoạn đầu: ECMWF System 51; giữ đầy đủ ensemble member.
- Quy ước tháng khởi tạo là LT=0; lấy dữ liệu đến biên 00 UTC đầu LT=7; LT=0 chỉ là đầu vào và không phát hành, sản phẩm vận hành là LT=1–6.
- PET Thornthwaite, log-logistic 3 tham số, ngưỡng D0–D4/W1–W4 và các quy định SPEI trong `README.tp` còn hiệu lực; calibration SPEI là 1981–2020.
- Đơn vị quan trắc đã xác nhận: mưa mm/tháng, nhiệt độ độ C.
- Miền predictor giữ [N=40, W=70, S=-20, E=150].
- Regridding sẽ được chọn bằng đánh giá hindcast ngoài mẫu để tối thiểu hóa sai số, không ấn định trước một phương pháp duy nhất.
- Đã đọc toàn bộ `ECMWF_SEAS5_System51_Variables_Guide.docx`; tài liệu không có hình/bảng nhúng ngoài nội dung XML và xác nhận ba nhóm temporal.
- `tp/slhf/sshf/tsr/ttr` là 24-hourly accumulated cumulative from initialization: step 24=0–24 h, step 48=0–48 h; daily increment=`X(t)-X(t-24)`. Diễn giải trước đó coi các step sau là interval độc lập là sai và đã được sửa.
- `tp` de-accumulate rồi nhân 1000 từ m sang mm. Flux/radiation de-accumulate rồi chia 86400 sang W m-2; quy ước dấu ECMWF positive downward; OLR positive upward xấp xỉ dấu âm của mean TTR.
- Người dùng xác nhận mọi giá trị lượng mưa `<0` phải được đặt bằng `0` trước khi xử lý tiếp; không dùng ngưỡng dung sai. Missing vẫn được giữ nguyên.
- `t2m/sst/stl1/msl` là 6-hourly instantaneous. Volumetric soil moisture là 24-hourly instantaneous/state m3 m-3, không phải accumulated.
- Không tự tạo stored step 0 khi CDS không cung cấp; với ngày đầu accumulated, step 24 đã là tích lũy từ initialization đến +24 h.
- Metric regridding/mô hình đã xác nhận: t2m dùng MAE, RMSE, bias/ME và correlation; pr dùng RMAE, bias/ME và correlation, không dùng MAE.
- Với SPEI-3/6 vận hành, ghép quan trắc đến tháng trước initial time với dự báo từ LT=0 trở đi; SPEI-6 tại LT=1 gồm bốn tháng quan trắc, LT=0 và LT=1.
- `t2m_ens` và `pr_ens` là ensemble mean của các AI members; `SPEI_ens` là AI ensemble với SPEI từ các AI members làm đầu vào.
- Heat index Thornthwaite dùng climatology fit trên calibration 1981–2020 và được lưu để dùng vận hành, tránh phụ thuộc các tháng tương lai trong năm dự báo.
- Mask `reg=1..7` là nguồn chính thức cho grid sản phẩm; không tự tái tạo từ shapefile.
- Không tải lớn, gửi job dài hoặc đổi dữ liệu gốc nếu chưa báo tài nguyên/lệnh và được xác nhận.
- Ngày 2026-09-22, người dùng cấp quyền tiếp tục tự thực hiện các bước kỹ thuật để đạt mục tiêu cuối cùng; các quyết định khoa học trọng yếu chưa xác nhận vẫn phải hỏi.
- Ngày 2026-09-30, người dùng xác nhận Codex tự thực hiện các download cần thiết để đạt mục tiêu cuối cùng và không cần hỏi lại từng lần; vẫn phải báo phạm vi/tài nguyên, giữ một worker, provenance và không thay đổi dữ liệu gốc.

## Quy định khoa học từ README.tp đã được tái xác nhận

- `README.tp` quy định PET Thornthwaite, water balance `pr - PET`, log-logistic 3 tham số fit theo grid/month/timescale, SPEI-1/3/6 và các ngưỡng D0–D4/W1–W4.
- `README.tp` nêu baseline model init 1981-01..2020-12 và quan trắc 1981-01..2021-06.
- `README.tp` nêu ensemble mean cho `pr_ens`/`t2m_ens`, nhưng không ensemble-mean SPEI; thay bằng stacking/weighting.

## Đã kiểm tra

- Theo chỉ đạo người dùng ngày 2026-10-02, giai đoạn download được tự động hóa và không chờ quyết định thủ công. Worker patched PID/PGID/SID 11530 đang request 1990-04; monitor detached PID/PGID/SID 12105, PPID=1, heartbeat mỗi 300 giây. Xác minh lúc 22:00 cho thấy đúng một Python CDS worker và downloader không bị gián đoạn khi thay riêng monitor.
- `scripts/download_ecmwf_baseline.sh` có circuit breaker mới: chỉ đếm lỗi `damaged tape` xác nhận trong manifest, defer sau 3 lần liên tiếp, ghi ledger TSV và tiếp tục tháng sau; lỗi khác vẫn retry exponential backoff. `bash -n` đạt.
- Đã thêm `baseline_download_monitor.sh`, submit/status scripts, `recover_deferred_ecmwf_gap.sh` và `config/ecmwf_known_damaged_tape_gaps.tsv`. Monitor tự restart downloader từ tháng đầu chưa đủ cặp raw trong dải 1990-04..2020-12; sau khi dải chính đủ/deferred, recovery chạy tuần tự dưới cùng downloader lock với cooldown 86400 giây. Smoke test `--once` nhận đúng downloader active và không tạo worker trùng; toàn bộ script mới đạt `bash -n`.
- Kiểm thử cô lập trong `/tmp/dr_gcm_monitor_test.HSXzMe` không gọi CDS: nhánh mất downloader ghi đúng `RESTART next=2099-01`; khi cặp raw giả đã đủ, nhánh hậu kỳ ghi đúng `RECOVERY_LAUNCH init=1989-03`; cả hai hoàn tất exit 0. Sau test, worker thật PID 11530 và monitor PID 12105 vẫn hoạt động, đúng một Python CDS request cho 1990-04.
- Audit chỉ đọc ngày 2026-10-02 21:46 ICT: downloader PID 26147 và shell con 26274 vẫn tồn tại, nhưng đang ở vòng retry 1800 giây cho instantaneous 1990-03; log ghi 79 lần `FAILED init=1990-03` tính đến snapshot. Lỗi mới vẫn là `AccessError` damaged tape `K0325300`, không phải lỗi validation cục bộ.
- Tiến độ thực tế tại snapshot: instantaneous 109/480 (1981-01..1989-02 và 1989-04..1990-02), accumulated 111/480 liên tục đến 1990-03, monthly 98/480 liên tục đến 1989-02. `ecmwf_seas51_1990-03_accumulated.nc` đã có và được validator nhận là `validated_existing`; instantaneous 1990-03 chưa có, không có file `.part` trong `raw_split`.
- Dung lượng snapshot: `data/ecmwf/raw_split` 102 GiB, `data/ecmwf/monthly` 1.9 GiB; filesystem `/work` còn khoảng 32 TiB. Monthly PID 14729 vẫn chờ 1989-03 đúng thiết kế; recovery và watchdog không chạy; recovery manifest 1989-03 vẫn `blocked_external`.
- Project vẫn không phải Git repository (`git status` trả về “Not a git repository”), vì vậy chưa có commit/diff provenance bằng Git; thay đổi tài liệu được kiểm tra trực tiếp theo nội dung file.
- Ngày 2026-09-30 phát hiện supervisor recovery đã gửi lặp 111 request cho cùng `stl1` lead 750 h và tất cả lỗi damaged tape `K0325300`. Đã dừng đúng process group recovery 30416; SIGTERM ban đầu không thoát do trap chỉ cleanup, sau đó SIGKILL đúng PGID và xác minh monthly PID 14729 không bị ảnh hưởng.
- Đã thêm circuit breaker cho single-lead damaged-tape trong `recover_ecmwf_instantaneous.py`, trạng thái manifest `blocked_external`, và sửa trap INT/TERM của supervisor để thoát thật. Unit test mục tiêu `5 passed in 1.59s`; full suite `66 passed in 16.18s`; `py_compile` và `bash -n` đạt.
- Request cuối có giới hạn lúc 09:49 ICT, CDS ID `4c3673c8-608f-48d2-93eb-ed994c796c39`, vẫn xác nhận lead `stl1=750 h` nằm trên damaged tape `K0325300`. Manifest đã ghi `blocked_external`; không có raw target thiếu được promote.
- CDS form chính thức của `seasonal-original-single-levels` không có lựa chọn ensemble member, nên không thể cô lập tape lỗi bằng cách chia member qua API dataset này.
- Đã khởi động downloader detached một worker cho 1989-04..2020-12 lúc 09:50 ICT: PID/PGID/SID 26147, child request bắt đầu ở 1989-04. Ước tính khoảng 381 initial months, xấp xỉ 380 GB raw và nhiều ngày đến vài tuần; `/work` còn 34 TB. Monthly worker PID 14729 tiếp tục chờ 1989-03 và không sinh output thiếu.
- Ngày 2026-09-29, sửa cấu hình climatology để dùng đúng `pr_mod`/`t2m_mod`, tách observation period 1981-01..2021-06 khỏi model initialization period 1981-01..2020-12, và giữ tương thích config phẳng cũ. Regression tests climatology: `4 passed in 1.71s`; full suite: `61 passed in 15.55s`.
- Inventory strict tạm ngày 2026-09-29: 98 instantaneous và 99 accumulated đều đọc được, grid/tập biến nhất quán, mỗi collection liên tục; strict chỉ thất bại vì thiếu instantaneous pair `1989-03`.
- Đã đọc `AGENTS.md`, `README.md`, `README.tp`, văn bản trong `Dr_GCM_Codex_1.docx`, toàn bộ `src/`, `tests/`, `config/` và `scripts/`.
- Có `download_ecmwf_pilot.py` và `config/ecmwf_pilot.json`; pilot ghi checkpoint manifest trước request đầu và sau từng nhóm.
- Test ngày 2026-09-20 sau thay đổi checkpoint: `9 passed in 5.64s` với `PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src python3 -m pytest -p no:cacheprovider -q`.
- Test toàn bộ ngày 2026-09-21: `24 passed in 107.77s`; không còn kẹt NFS.
- Thêm `src/dr_gcm/baseline.py`, `tests/test_baseline.py`: Linear/Ridge alpha explicit, scaler fit training-only, constant feature, strict missing, reusable NetCDF model và atomic predictions; `4 passed in 84.21s`; full suite trước bổ sung simple baselines: `53 passed in 128.41s`. Bổ sung monthly climatology fit training-only và persistence từ đúng tháng init−1; baseline tests `6 passed in 97.58s`; full suite `55 passed in 129.95s`.
- Nâng `src/dr_gcm/inventory.py`, `tests/test_inventory.py`, `config/inventory_split.json`: kiểm tra chuỗi initialization month liên tục/không trùng và exact pairing giữa nhóm instantaneous/accumulated; unit test `3 passed in 115.45s`; full suite ngày 2026-09-22: `56 passed in 175.43s`.
- Snapshot strict `outputs/inventory/inventory_split_20260922.json`: 38 file instantaneous + 38 file accumulated, tất cả đọc được, grid và tập biến nhất quán, init liên tục 1981-01..1984-02, không thiếu/trùng và hai nhóm ghép cặp hoàn toàn. Kích thước lần lượt 27,445,670,728 và 10,505,823,754 bytes.
- Sửa `src/dr_gcm/climatology.py` để giữ chiều member, loại LT=0 khỏi climatology phát hành, reject init trùng/grid-member không nhất quán và tích lũy từng file không phụ thuộc Dask; test mới `2 passed in 99.15s`; full suite sau sửa: `58 passed in 160.12s`.
- Pilot monthly thật lần đầu phát hiện `valid_time` được xarray mở như data variable nên không đi cùng từng field; không có output được promote. Đã sửa `monthly.py` để kiểm tra rồi promote `valid_time(forecast_period)` thành coordinate và thêm regression test; monthly tests `5 passed in 103.57s`, full suite `59 passed in 160.03s`.
- Chạy lại pilot `1981-01` thành công: `data/ecmwf/monthly/ecmwf_seas51_1981-01_monthly.nc`, 20,376,941 bytes, SHA-256 `74cdba1c79222e5c16d89188042d47dc2c0bd4683361bb4d3ad5a3b5c748f041`. Đúng 9 biến, 25 members, LT=0..6, 60×80, có init/valid time và provenance. Tất cả biến ngoài SST không missing; SST thiếu trên 1,545/4,800 grid cell với mask cố định hoàn toàn qua member/lead. Range: t2m -29.72..39.64 °C, pr 0..1533.81 mm/month, msl 992.64..1036.87 hPa.
- Thêm `scripts/build_monthly_baseline.sh` và `scripts/monthly_baseline_status.sh`: một worker, flock/PID/log, resume bằng validator, chờ raw pair và dừng ngay khi lỗi. `bash -n` đạt; smoke test `1981-01..1981-01` validate file cũ, không ghi đè và complete thành công.
- Supervisor monthly toàn dải được tách phiên lúc 11:05 ICT ngày 2026-09-22: PID/PGID/SID `24597`, PPID=1, dải 1981-01..2020-12, poll 300 giây; process con ban đầu PID 24660. Không khởi động bản sao.
- Supervisor monthly PID 24597 đã dừng ngoài dự kiến sau `PROCESS init=1984-04` lúc 18:49 ngày 2026-09-22, không có `SUCCESS`/`FAILED`, traceback, OOM, `.part` hay PID file còn lại; 39 output đến 1984-03 vẫn hợp lệ. Nguyên nhân chính xác chưa xác định, phù hợp với cả shell và child bị môi trường ngoài kết thúc.
- Đã resume an toàn từ đúng `1984-04` lúc 07:38 ngày 2026-09-23 bằng supervisor PID/PGID/SID `29447`, PPID=1, một worker; child PID 30075 thực sự đang đọc raw 1984-04 khi xác minh.
- Thêm `src/dr_gcm/temporal_cv.py`, `tests/test_temporal_cv.py`: expanding rolling-origin theo năm, block/gap explicit, strict contiguous years và no-overlap, JSON plan atomic; `4 passed in 76.40s`.
- Thêm `src/dr_gcm/operational.py`, `tests/test_operational.py`: ghép 5 tháng quan trắc trước init với LT=0..6, broadcast history qua member, strict valid_time/monthly continuity và atomic output; `4 passed in 89.74s`; full suite: `45 passed in 123.10s`.
- Thêm `src/dr_gcm/spei_workflow.py`, `tests/test_spei_workflow.py`: CLI fit/apply calibration 1981-2020, strict monthly axis/units, parameter/SPEI validators và atomic output; sửa scalar `timescale` khi merge SPEI-1/3/6. SPEI tests `8 passed in 105.88s`.
- Sửa `src/dr_gcm/spei.py` ngày 2026-09-21: heat index/exponent Thornthwaite được fit từ climatology calibration có đủ 12 tháng, lưu thành dataset và bắt buộc truyền lại khi tính PET/water balance; loại bỏ cách cũ fit riêng theo forecast year. Test SPEI `5 passed in 99.89s`; full suite sau tất cả thay đổi: `38 passed in 97.36s`.
- File/module mới ngày 2026-09-21: `src/dr_gcm/verification.py`, `tests/test_verification.py`; metrics liên tục và contingency đã xác nhận, paired-missing, EDI/SEDI không tự edge-correct; test mục tiêu `5 passed in 82.39s`. Đã tránh lỗi `xr.corr` của xarray HPC thiếu biểu tượng dask bằng công thức Pearson thuần xarray.
- File/module mới ngày 2026-09-21: `src/dr_gcm/drought.py`, `tests/test_drought.py`; phân cấp D4..W4 và P(D1)..P(D4), strict D4<-2, kiểm tra mẫu số/missing, atomic output; test mục tiêu `4 passed in 93.89s`.
- File/module mới ngày 2026-09-21: `src/dr_gcm/monthly.py`, `tests/test_monthly.py`; CLI tổng hợp LT=0..6 trên lưới gốc, giữ 25 members, strict timestep/unit, de-accumulation, `.part` + validation + atomic promote. Test mục tiêu: `4 passed in 82.76s`; full suite sau thay đổi: `28 passed in 120.17s`.
- File vừa thay đổi ngày 2026-09-30: `src/dr_gcm/recover_ecmwf_instantaneous.py`, `tests/test_recover_ecmwf_instantaneous.py`, `scripts/supervise_ecmwf_recovery.sh`, `README.md`, `CODEX.md`, `Memory.md`. Các thay đổi ngày 2026-09-29 ở climatology/config/diagnostic vẫn được giữ nguyên.
- Đã cập nhật `config/ecmwf_pilot.json` và `download_ecmwf_pilot.py` để request/validate timestep riêng theo từng nhóm; accumulated dùng 24/48/72 và manifest ghi `leadtime_hour_by_group`. Test tương ứng đã cập nhật.
- Đã thêm `src/dr_gcm/download_ecmwf_baseline.py` và `tests/test_download_ecmwf_baseline.py`; script baseline hiện gọi downloader mới.
- Mặc định tách `instantaneous` (0..LT7 mỗi 6 h; validator cho phép CDS bỏ step 0) và `accumulated` (24..LT7 mỗi 24 h); soil moisture là nhóm riêng tắt mặc định.
- Chỉ promote nguyên tử từ `.part` sau validation biến, 25 members, reference time và toàn bộ lead; file tồn tại cũng phải validate trước khi skip; manifest checkpoint theo nhóm.
- Kiểm tra 2026-09-20: JSON, Python compile, Bash syntax, dry-run 2026-02 đạt; unit test downloader mới `7 passed in 0.74s`.
- Full test suite được thử lại với timeout 90 giây nhưng tiến trình vào `nfs_wait_killable`, không sinh kết quả và đã kết thúc ở timeout; không còn process pytest.
- Người dùng đã duyệt tự thực hiện theo lộ trình và chuẩn bị job tự động để có thể thoát phiên.
- Request trực tiếp 1981-01 PID 25283, CDS ID `85fe41f1-80bb-4121-8b9a-953909870b74`, đang running khi supervisor được bật.
- Supervisor PID 3212 đã tách phiên thành công: PPID=1, PGID=SID=3212; nó chờ PID 25283 kết thúc rồi chạy 1981-01..2020-12 với một worker.
- Đã thêm khóa `flock`, PID, retry backoff 300..1800 giây và `--retry-partial`; file hoàn chỉnh không bị overwrite, chỉ file `.part` của request lỗi được tải lại.
- Script kiểm tra read-only: `bash scripts/ecmwf_baseline_status.sh`. Log supervisor và worker ở `outputs/logs/`.
- Đã thêm hàm dùng chung để đặt mọi mưa âm về 0, de-accumulate TP step 24-hour, đổi m sang mm và ghi provenance; đã nối vào climatology và SPEI water balance.
- Đã thêm aggregation tháng theo interval start = `valid_time-24h`, kiểm tra chuỗi ngày liên tục/đủ số ngày từng tháng và cộng daily precipitation đã clip. Unit test bao phủ clipping, giữ missing, không sửa input, timestep thiếu, biên tháng, tháng thiếu và water balance.
- Kiểm tra cú pháp toàn bộ file Python vừa sửa đạt. Pytest mục tiêu được thử với timeout 45 giây nhưng kẹt tại `nfs_wait_killable`; timeout đã kết thúc và không còn process test. Không tuyên bố test động đạt.
- Nguồn C3S/ECMWF ngày 2024-10-10 cho biết volumetric soil moisture được đưa vào CDS cùng forecast thời gian thực 2024-10, daily-only, System 51 có các lớp `swvl1..4`, GRIB2 CCSDS/ecCodes >=2.33. Kết hợp với `MarsNoDataError` cho init 1981-01, chưa có bằng chứng về coverage hindcast 1981–2020.
- Đã thêm `src/dr_gcm/inventory.py`, `config/inventory.json`, `tests/test_inventory.py`.
- Inventory thật: 98/98 GCM đọc được; grid, member và tập biến nhất quán; cả 98 thiếu `tp`, `slhf`, `sshf`, `tsr`, `ttr`, `swvl1`.
- Báo cáo chuẩn: `outputs/inventory/inventory_20260919_v2.json` (v1 giữ lại nhưng datetime bị biểu diễn dạng số và đã bị thay thế bởi v2).
- `data` là symlink tới `/work/projects/G09/Dr_VNU/GCM4Dr`; `outputs` tới `/work/projects/G09/Dr_VNU/Dr_GCM_outputs`.
- Quan trắc dùng được: rainfall 504 tháng (1980-01..2021-12), temperature 732 tháng (1961-01..2021-12), grid 40×68, lon 101.125..110.875 tăng, lat 7.625..24.375 tăng. Cả hai ghi metadata `var_unit`; người dùng đã xác nhận đơn vị vật lý là mm/tháng và độ C.
- Mask dùng được: grid trùng observation 40×68, 500 cell hữu hạn, `reg=1..7`.
- Shapefile `Vietnam7.{shp,shx,dbf,prj}` tồn tại đúng thư mục `VN_SubRegs1`.
- Filesystem `/work`: 123 TB tổng, 35 TB trống tại thời điểm kiểm tra.

## Downloader baseline đã dừng có kiểm soát

Phần này chỉ mô tả downloader legacy trong `data/ecmwf/raw/`, không phải downloader split hiện hành.

- Theo xác nhận của người dùng, đã gửi SIGTERM tới process group 16490; các PID 16490, 16497 và 40192 đều đã kết thúc.
- Lệnh cũ: `download_ecmwf_baseline.sh 1981-01 2020-12 1`.
- Đã có 98/480 tệp liên tục từ 1981-01 đến 1989-02; không có tệp rỗng.
- Tổng kích thước 70,210,020,947 bytes (~65.4 GiB); trung bình 716,428,785 bytes/tháng. Nếu cùng kích thước, toàn bộ khoảng sẽ khoảng 344 GB thập phân, còn khoảng 274 GB.
- Trước khi dừng, job kẹt tại 1989-03; từ 2026-09-15 có nhiều `MarsRuntimeError`. Request cuối bắt đầu 2026-09-18 14:40 ICT và log lần cuối cập nhật 16:21 ICT.
- Không xóa hoặc sửa 98 tệp và log cũ; PID file hiện là dấu vết lịch sử, không chứng minh job còn chạy.

## Lỗi/rủi ro đã biết

- CDS/MARS instantaneous 1989-03 thất bại với request lớn vì damaged tape `K0325300` (`AccessError`, error code `-2`). Ngày 2026-09-29 người dùng duyệt dừng retry và diagnostic: watchdog PID 14289 cùng downloader PGID 14499 đã được SIGTERM an toàn; monthly supervisor PID 14729 vẫn chờ, không có file bị xóa.
- Diagnostic ban đầu dùng 21 MB và manifest riêng: bốn biến đều thành công với các lead rời `6/24/48` và `1680/3360/5136`; block bốn biến `2520..2688` thất bại. Khi tách biến trên cùng block, `t2m/sst/msl` thành công, `stl1` thất bại; hai nửa STL1 vẫn lỗi nhưng từng lead đơn `2520` và `2688` đều thành công. Kết luận: dữ liệu còn truy xuất được, lỗi phụ thuộc cách MARS gom nhiều step của parameter 139 trên tape, không phải mất hoàn toàn tháng. Không skip tháng hoặc promote file ghép trước khi validate đủ 856 lead (6..5136 h cho init 1989-03) và 25 members.

- Tệp GCM mẫu `ecmwf_seas51_1989-02_all.nc` mở được nhưng chỉ có 4/10 biến yêu cầu: `t2m`, `sst`, `stl1`, `msl`; thiếu precipitation, latent/sensible heat flux, net solar/thermal radiation và soil moisture.
- Mẫu có 25 members, grid 1° (60×80; lat giảm 39.5..-19.5, lon 70.5..149.5), 848 forecast periods từ +6 h đến +5088 h. Step 0 không có trong bốn biến tức thời dù request gồm step 0.
- Vì archive hiện thiếu biến, không được coi 98 tệp là dữ liệu baseline hoàn chỉnh và chưa được aggregate/regrid.
- Đã sửa script retry để lấy exit status trong nhánh `else`; không còn lỗi `while ! command; status=$?` luôn ghi `exit=0`. Chưa khởi động lại downloader baseline.
- Downloader cũ bỏ qua theo `Path.exists()`; downloader baseline mới validate đầy đủ trước skip/promote và dùng `data/ecmwf/raw_split/`.
- SPEI đã có CLI fit/apply, metadata/provenance và unit/integration tests; vẫn thiếu kiểm định số học với bộ tham chiếu SPEI độc lập trước khi dùng nghiệp vụ.

## Trạng thái CDS pilot

- Người dùng đã duyệt ba request nhỏ cho init 1981-01, lead hours 0/6/24/30, 25 members và miền [40, 70, -20, 150].
- Pilot cũ PID 22693 đã kết thúc mà không có `.part`, NetCDF hay manifest; nguyên nhân chưa xác định.
- Pilot PID 302 đã kết thúc lúc 2026-09-20 11:11 ICT; manifest được ghi đầy đủ, không còn tiến trình chạy.
- `instantaneous` thành công: 25 members, grid 60×80, đủ `t2m/sst/stl1/msl`, nhưng request step 0/6/24/30 chỉ trả 6/24/30; step 0 không có.
- `accumulated` thành công: 25 members, đủ `tp/slhf/sshf/tsr/ttr`; request step 0/6/24/30 chỉ trả step 24. Theo guide, các biến này cumulative from initialization và phải lấy hiệu các step 24-hour liên tiếp trước aggregation. Metadata: `tp` m; flux/radiation J m-2.
- Đối chiếu range step 24 phù hợp ý nghĩa guide: `tp` không âm; `slhf/sshf` chủ yếu âm; `tsr` dương; `ttr` âm. Đây chỉ xác minh dấu/đơn vị, chưa xác minh cumulative difference vì file mới có một step.
- NetCDF ghi `GRIB_stepType=instant` cho cả năm biến accumulated, xung đột với `long_name` time-integrated, đơn vị J m-2/m và guide. Không được dùng riêng attribute này để phân loại temporal semantics; guide cộng với chuỗi step/value là căn cứ kiểm tra.
- `soil_moisture` thất bại: CDS request ID `d009eced-9ebe-4675-ad2a-01dfaa877ed7`, `MarsNoDataError` cho `volumetric_soil_water_layer_1` với cả `levtype=sfc` và `levtype=sol`.
- Pilot accumulated 24/48/72 request ID `c58e76c2-720b-4a76-b8c8-4219c793ebf0` hoàn tất thành công. Ngày 2026-09-21, validator Python và toàn bộ test suite đạt; file được promote nguyên tử sang `.nc`, vẫn có 3,691,903 bytes và SHA-256 `5605d86976c5d6b43f4b6cd679aacd65f248d744e8dc3b44ed6a2796a974111e`.
- Validation bằng `ncdump`: đúng 25 members, năm biến `tp/slhf/sshf/tsr/ttr`, grid 60x80, forecast period đúng 24/48/72 giờ; valid time là 1981-01-02/03/04 00 UTC.
- Sau thay đổi mã, checksum file raw pilot vẫn là `5605d86976c5d6b43f4b6cd679aacd65f248d744e8dc3b44ed6a2796a974111e`; không sửa dữ liệu gốc.
- NCO xác nhận daily mean của step24, hiệu 48-24 và hiệu 72-48: `tp=5.220/5.108/5.045 mm day-1`; các flux/radiation giữa ba ngày có độ lớn tương đương và dấu phù hợp guide.
- Hai hiệu ngày đều không có missing trên 120,000 phần tử. `tp` có 351 và 416 giá trị âm, min `-3.8147e-6 m = -0.0038147 mm`. Theo quyết định đã xác nhận, pipeline dẫn xuất sẽ đặt toàn bộ các giá trị này bằng 0; file raw/pilot `.part` không bị sửa.
- `slhf` âm tại 119,986/120,000 và 119,892/120,000 điểm; `sshf` chủ yếu âm; `tsr` dương và `ttr` âm tại toàn bộ điểm của cả hai hiệu.
- Hai file pilot cũ hợp lệ và manifest được giữ trong `data/ecmwf/pilot/`; file pilot 24/48/72 đã được validate và promote nguyên tử sang `.nc`.
- Pilot soil moisture System 51 init 2024-10, step 24/48/72, request ID `29a58789-4e0d-44cb-baaa-15ef5ae95d63` thất bại lúc 17:05:18 ICT với `MarsNoDataError`; không tạo file `.part`. Cả 1981-01 và 2024-10 đều không trả dữ liệu, nhưng chưa suy diễn thành toàn bộ archive không tồn tại.

## Trạng thái downloader split hiện hành

- Recovery chuyên dụng được thêm tại `src/dr_gcm/recover_ecmwf_instantaneous.py`, test tại `tests/test_recover_ecmwf_instantaneous.py`, status script `scripts/ecmwf_recovery_status.sh`. Test recovery `4 passed`; full suite `65 passed in 14.81s`. Dry-run 1989-03 xác nhận 856 lead và 32 request khởi đầu. Worker PID/PGID/SID 27250, PPID=1, bắt đầu 21:40 ICT ngày 2026-09-29; log `outputs/logs/ecmwf_recovery_1989-03.log`, manifest `data/ecmwf/recovery/1989-03-instantaneous/recovery_manifest.json`. Supervisor detached PID/PGID/SID 30416, PPID=1, poll 300 giây, lock/PID/log riêng; snapshot 21:53 ICT có 7 chunk tải xong, không có chunk lỗi. `bash -n` đạt cho recovery supervisor/status/watchdog; thử supervisor trùng trả đúng exit 75 và không ảnh hưởng worker.

- Snapshot cuối 2026-09-29: instantaneous 98/480 đến 1989-02; accumulated 99/480 đến 1989-03; monthly 98/480 đến 1989-02. Watchdog/downloader đã dừng theo duyệt; monthly supervisor PID 14729 còn chạy và chờ instantaneous 1989-03.

- Snapshot strict lúc 08:46 ICT ngày 2026-09-22: 38/480 file instantaneous và 38/480 file accumulated đã hoàn tất, liên tục 1981-01..1984-02, exact pairing; worker đang xử lý 1984-03.
- Process supervisor PID 3212, worker shell PID 8128 và downloader Python PID 39729 còn chạy khi kiểm tra; không suy diễn trạng thái CDS chỉ từ thời gian process.
- Lúc 10:51 ICT ngày 2026-09-22, downloader đã tiến tới init `1984-05`; supervisor PID 3212 và worker PID 8128 vẫn còn chạy.
- Lúc 07:35 ICT ngày 2026-09-23: 56/480 cặp raw hoàn chỉnh liên tục đến 1985-08 (55,859,495,392 bytes tổng); downloader đang request 1985-09. Các retry tại 1985-05/06/08 đều đã tự phục hồi, không bỏ qua tháng.
- Trạng thái hiện hành: chỉ downloader PID 26147 được phép chạy từ 1989-04 với một worker; không khởi động bản sao hoặc tăng concurrency.
- Đã sửa thứ tự khởi tạo `log_dir`/`run_log` trước khi lấy `flock`; thay đổi chỉ tác động các lần chạy sau.
- Đường dẫn observation gốc `/home/tanpv/Data/562_VNU/0.25_VN/` không tồn tại trên host; rainfall và T2m vẫn dùng được qua `data/obs/`; Tx/Tm chưa tìm thấy.

## Câu hỏi mở ưu tiên

1. Xác minh soil moisture có được backfill cho hindcast System 51 hay chỉ có từ real-time 2024-10; nếu không có 1981–2020, cần khảo sát nguồn soil moisture từ GCM reforecast khác. Không dùng reanalysis và không loại predictor này nếu chưa có quyết định mới của người dùng.
2. Thiết kế blocked hindcast CV cho regridding theo bộ metric đã xác nhận, đánh giá riêng theo lead và mùa.
3. Xác nhận huấn luyện chung/riêng theo lead và mùa, mô hình AI/tuning, xử lý outlier không phải mưa âm và nền tảng web ở các giai đoạn tương ứng.

## Bước tiếp theo chính xác

- Không dừng downloader PID 11530. Monitor PID 12105 tự theo dõi/restart và duy trì một worker; kiểm tra bằng `bash scripts/baseline_download_monitor_status.sh` và `bash scripts/ecmwf_baseline_status.sh`.
- Raw snapshot trước 1990-04 có 109 instantaneous và 111 accumulated; hai gap đã đăng ký là 1989-03 và 1990-03. Monthly có 98 output đến 1989-02 và PID 14729 tiếp tục chờ cho đến khi recovery tạo đủ raw hợp lệ.
- Khi dải 1990-04..2020-12 hoàn tất/deferred, monitor tự chạy recovery 1989-03 rồi 1990-03 và các gap mới, tuần tự, không đồng thời downloader, cooldown 24 giờ nếu tape vẫn lỗi.
- Watchdog đã đạt `bash -n` và kiểm thử `--once` không tạo supervisor trùng; daemon PID/SID/PGID `6250`, PPID=1, heartbeat đầu tiên lúc 15:38:22 ICT ngày 2026-09-23. Thử bản sao trả đúng exit 75.
- Dùng inventory strict định kỳ để phát hiện gap/duplicate/pair mismatch; kiểm tra giao kỳ huấn luyện 1981–2020 khi archive đủ.
- Thiết kế protocol so sánh regridding trên hindcast ngoài mẫu trước khi triển khai regrid toàn archive.

## Lệnh kiểm tra tiếp nếu phiên bị gián đoạn

```bash
ps -eo pid,ppid,etime,stat,args | rg 'download_ecmwf_baseline' | rg -v 'rg '
bash scripts/ecmwf_baseline_status.sh
bash scripts/monthly_baseline_status.sh
python3 -c 'import json; d=json.load(open("data/ecmwf/recovery/1989-03-instantaneous/recovery_manifest.json")); print(d["status"], d.get("blocked_reason"))'
PYTHONPATH=src python3 -m dr_gcm.inventory --config config/inventory_split.json --output outputs/inventory/inventory_split_YYYYMMDD.json --strict
ps -o pid,ppid,stat,etime,args -p 16490,16497,40192
tail -40 outputs/logs/ecmwf_baseline_download.log
pgrep -af 'dr_gcm.download_ecmwf_pilot'
cat outputs/logs/ecmwf_pilot_1981-01.pid
tail -40 outputs/logs/ecmwf_pilot_1981-01.log
find -L data/ecmwf/pilot -maxdepth 1 -type f -printf '%p|%s bytes\n'
find -L data/ecmwf/raw -maxdepth 1 -type f -name 'ecmwf_seas51_*_all.nc' -printf '.' | wc -c
PYTHONDONTWRITEBYTECODE=1 python3 -m pytest -p no:cacheprovider -q
ps -o pid,pgid,stat,etime,args -p 27767
tail -40 outputs/logs/ecmwf_pilot_accumulated_24_72.log
ps -o pid,ppid,pgid,stat,etime,args --forest -g 34204
tail -40 outputs/logs/ecmwf_pilot_soil_moisture_2024-10.log
```

## Cập nhật quyết định và trạng thái ngày 2026-10-03

- Người dùng xác nhận soil moisture là biến bắt buộc, không được loại; nếu System 51 thiếu hindcast đồng nhất phải trình phương án nguồn thay thế/ghép dữ liệu.
- Người dùng đồng ý rolling-origin CV và mô hình riêng theo lead nhưng gộp thông tin tháng/mùa bằng encoding. Tham số cụ thể của CV chưa được chốt.
- Ứng viên đã duyệt: Ridge, gradient-boosted trees và foundation model; FM cụ thể và tài nguyên chưa được chọn.
- Người dùng yêu cầu hoàn thành download và báo khi xong. Tiêu chí xong: đủ raw groups/biến/member/lead cho 1981-01..2020-12, không còn gap/deferred và inventory strict đạt.
- Audit khoảng 15:45 ICT: monitor PID 12105 và đúng một CDS worker đang chạy init 1991-12; có 127 instantaneous, 131 accumulated, 98 monthly; bốn instantaneous gap là 1989-03, 1990-03, 1991-01, 1991-03.
- Inventory tạm `/tmp/dr_gcm_inventory_check_20261003.json`: mọi file hiện có đọc được, grid/tập biến nhất quán, nhưng pairing chưa đạt do bốn gap.
- Full test suite: `66 passed in 20.81s`.

### Sửa recovery cooldown ngày 2026-10-03

- Audit phát hiện circuit breaker cũ giữ `attempt_count` vĩnh viễn; sau khi đạt giới hạn, mọi lần recovery hậu cooldown sẽ thoát trước khi gửi request, nên gap không thể tự phục hồi dù tape đã được sửa.
- Đã thêm attempt-cycle reset chỉ cho single-lead có lỗi damaged-tape khi manifest trước là `blocked_external`. Provenance giữ `total_attempt_count`, `attempt_cycle_reset_utc` và `recovery_cycles`; giới hạn ba attempt trong mỗi cycle vẫn còn.
- `scripts/recover_deferred_ecmwf_gap.sh` truyền `--reset-blocked-attempts`; global download/recovery locks và cooldown 24 giờ không đổi.
- Xác minh: Python compile đạt, `bash -n` đạt, recovery tests `6 passed in 1.44s`, full suite `67 passed in 17.12s`. Worker baseline PID 38743 vẫn chạy duy nhất cho init 1991-12 và không bị tác động.
- File thay đổi: `src/dr_gcm/recover_ecmwf_instantaneous.py`, `scripts/recover_deferred_ecmwf_gap.sh`, `tests/test_recover_ecmwf_instantaneous.py`, `README.md`, `CODEX.md`, `Memory.md`.

## Snapshot tiếp tục ngày 2026-10-04

- Kiểm tra chỉ đọc lúc khoảng 07:20 ICT: monitor PID 12105 còn hoạt động và heartbeat đều mỗi 300 giây; downloader giữ đúng một Python CDS worker, đang request init `1993-02` (request ID `1d0a788a-b753-40fd-a82a-9aac293b2c17`). Không khởi động, dừng hoặc thay đổi job nào.
- Tiến độ đã xác minh: 140/480 instantaneous, 145/480 accumulated và 98/480 monthly. Init `1993-01` đã hoàn tất lúc 07:07 ICT; monthly worker PID 14729 vẫn chờ đúng tại gap `1989-03`.
- Ledger hiện có năm gap damaged-tape: `1989-03`, `1990-03`, `1991-01`, `1991-03`, `1992-04`. Vì còn gap/deferred nên tiêu chí download hoàn tất và inventory strict chưa đạt.
- Dung lượng: `data/ecmwf/raw_split` khoảng 131 GiB, `data/ecmwf/monthly` khoảng 1.9 GiB; filesystem `/work` còn khoảng 32 TiB.
- Repository vẫn không có Git metadata tại project root; `git status` không khả dụng. Không chạy test vì lượt này chỉ audit trạng thái và không sửa mã.
