Add two session prompts to clear the dependency-freshness backlog
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
file length / file-length (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
palette drift / palette (push) Waiting to run
shared gate tests / gate unit tests (push) Waiting to run

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Krzysztof Rudnicki 2026-09-12 17:31:01 +02:00
parent 675b3859b3
commit 2f7f609754
2 changed files with 268 additions and 0 deletions

View File

@ -0,0 +1,127 @@
# TODO — utils deps, session 1 of 2: the mechanical bumps
REMOVE ME AFTER FINISH
Running order: **this file first**, then `TODO-deps-02-major-upgrades.md`.
Session 2 does not depend on this one having run, but doing this first shrinks
the gate output to just the three majors, so a failure in session 2 is
unambiguous.
## Why this exists
`~/src/utils` has been red on the **dependency freshness** CI workflow since
2026-09-11 — every run on `main` since commit `001670f` has failed. It is not
a broken build: upstream moved and the exact pins did not. Measured
2026-09-12 with `./scripts/check_dependency_freshness.sh --all` (exit 1,
29 findings across 9 sub-packages).
This session does the **16 low-risk bumps only**. The three majors
(`very_good_analysis 11`, `vitest`/`@vitest/coverage-v8 5`, `pnpm 12`) are
session 2's job — do not touch them here, they need hand edits and a
separate blast-radius check.
`~/src/utils` is a shared monorepo: 8 Flutter apps consume its Dart packages
(`home_inventory`, `kuhylog`, `lyricanki`, `punchme`, `todo`, `untools`,
`restaurant-rater`, `epopeja_karta`) and 4 TS repos consume `@kuhyx/ts-core`
/ `@kuhyx/web-ui` (`europe-county-map`, `iron-and-anvil`,
`awesome-mcp-explorer`, `konbini-67`). Breaking a pin here breaks twelve
downstream repos, which is why every sub-package's suite must go green before
you commit.
## Read first
- `rules/dependency-freshness.instructions.md` — exact pins, stable only, the
two allowlist classes, and **never `--no-verify`**.
- `dependency-freshness.allowlist.yaml` — top-of-file comment explains the two
entry classes. It already holds ONE active entry (`npm:typescript` pinned
6.0.3, `blocked_by: transitive:typescript-eslint@8.70.0`). **Leave it
alone.** It is fleet-wide and correct; touching TypeScript is out of scope
for both sessions.
- `scripts/run_subproject_tests.sh` — pre-commit runs hooks from the git root,
but each sub-package's pytest config is relative to its own directory. This
wrapper supplies the missing `cd`. Use it; do not hand-roll one.
## The 16 bumps
Exact, with the file and line the gate named:
| Ecosystem | Package | From → To | File |
|---|---|---|---|
| toolchain | node | 24.20.0 → 24.21.0 | `.github/workflows/ts-core-tests.yml:27` |
| toolchain | node | 24.20.0 → 24.21.0 | `.github/workflows/web-ui-tests.yml:27` |
| pypi | ruff | 0.16.5 → 0.16.7 | `crdt-sync/requirements.txt:11` |
| pypi | types-requests | 2.33.0.20260712 → 2.33.0.20260906 | `crdt-sync/requirements.txt:12` |
| pypi | ruff | 0.16.6 → 0.16.7 | `freedays/requirements.txt:10` |
| pypi | ruff | 0.16.5 → 0.16.7 | `gatelock/requirements.txt:10` |
| pub | test | 1.31.2 → 1.32.0 | `crdt_sync_dart/pubspec.yaml:17` |
| pub | flutter_secure_storage | 11.0.0 → 11.1.1 | `crdt_sync_flutter/pubspec.yaml:21` |
| npm | eslint | 10.9.1 → 10.10.0 | `ts_core/package.json:34` |
| npm | typescript-eslint | 8.68.0 → 8.70.0 | `ts_core/package.json:36` |
| npm | eslint | 10.9.1 → 10.10.0 | `web_ui/package.json:43` |
| npm | typescript-eslint | 8.68.0 → 8.70.0 | `web_ui/package.json:48` |
| npm | @testing-library/user-event | 14.6.6 → 14.6.7 | `web_ui/package.json:39` |
| npm | @types/react | 19.2.18 → 19.3.0 | `web_ui/package.json:40` |
| npm | @types/react-dom | 19.2.5 → 19.3.0 | `web_ui/package.json:41` |
| npm | react + react-dom | 19.2.8 → 19.3.0 | `web_ui/package.json:33,46` |
`react` and `react-dom` must move together — a split version pair is a
runtime error, not a lint finding.
Note `typescript-eslint 8.70.0` is already the version the allowlist entry
names as the TS-7 blocker. Bumping to it is expected and does **not**
invalidate that entry; do not edit the allowlist.
## Constraints you would otherwise rediscover painfully
- **pnpm only, never npm.** `@kuhyx/web-ui` is consumed as `&path:/web_ui`;
npm cannot install a monorepo subdirectory and running it locks the repo
into a broken state. Local pnpm is 11.26.0 (leave it — session 2 owns the
pnpm 12 move), node is v24.18.0 via nvm. The node bumps above are **CI
workflow pins only**; your local node does not need to match.
- **250-line cap** on every file, code and prose, enforced by
`scripts/check_file_length.sh`.
- **No `# noqa`, no `type: ignore`, no per-file-ignores** without asking
first, every time. Fix the underlying issue.
- **Never `--no-verify`.** If a hook fails, fix the failure.
- Heavy commands go through `~/.claude/scripts/capped.sh` (2 GiB / 10% CPU;
raise per-invocation with `CAP_MEM=4G CAP_CPU_PCT=20`).
- Work on `main`; branch creation is blocked by a hook. Stage narrowly — no
blanket `git add .`.
## Procedure
1. Apply the 16 edits above. Exact pins, no carets (the `very_good_analysis`
carets stay as-is — they are session 2's).
2. Regenerate lockfiles where the ecosystem has one:
- `crdt_sync_dart`, `crdt_sync_flutter`: `dart pub get` / `flutter pub get`
- `ts_core`, `web_ui`: `pnpm install` (in each package directory)
- Python requirements have no lockfile here.
3. Run each touched sub-package's suite and fix what breaks:
- `scripts/run_subproject_tests.sh crdt-sync`
- `scripts/run_subproject_tests.sh freedays`
- `scripts/run_subproject_tests.sh gatelock`
- `cd crdt_sync_dart && dart test`
- `cd crdt_sync_flutter && flutter test`
- `cd ts_core && pnpm lint && pnpm test`
- `cd web_ui && pnpm lint && pnpm test`
The React 19.2→19.3 bump is the one most likely to surface a test change;
`eslint 10.10.0` may add a rule that fires. Fix the code, not the config.
4. `./scripts/check_dependency_freshness.sh --all` — expect exit 1 still, but
**only** the three majors remaining (very_good_analysis ×4, vitest ×2,
@vitest/coverage-v8 ×2, pnpm ×2). If anything else is listed, you missed a
bump.
5. `pre-commit run --files <changed files>`.
6. Commit and push with `~/.claude/scripts/finish_auto.sh` (it runs the gate,
stages narrowly, commits, pushes and watches CI with no LLM turns). Pass
the changed files explicitly — it does not stage untracked files on its
own.
## Exit condition
- `./scripts/check_dependency_freshness.sh --all` lists **only** the three
major upgrades named above; every other finding is gone.
- Every sub-package suite listed in step 3 passes.
- Pushed to `main`, and the **dependency freshness** workflow is the only red
CI check left on the repo (it stays red until session 2 lands — that is
expected and is why session 2 exists).
- Delete this file as part of the final commit.

View File

@ -0,0 +1,141 @@
# TODO — utils deps, session 2 of 2: the three major upgrades
REMOVE ME AFTER FINISH
Running order: `TODO-deps-01-mechanical-bumps.md` first, then **this file**.
If session 1 has not run, `./scripts/check_dependency_freshness.sh --all` will
list ~16 extra low-risk findings alongside the three below — ignore them here
and do session 1 first, or the gate can never reach exit 0.
## Why this exists
`~/src/utils` has been red on the **dependency freshness** CI workflow since
2026-09-11. Session 1 cleared the mechanical bumps. What is left are three
major-version moves, each with real breaking-change surface, measured
2026-09-12:
| Ecosystem | Package | From → To | Files |
|---|---|---|---|
| pub | very_good_analysis | `^10.3.0` → `11.0.0` | `crdt_sync_flutter/pubspec.yaml:37`, `design_system/pubspec.yaml:20`, `github_device_auth/pubspec.yaml:21`, `sync_settings_ui/pubspec.yaml:25` |
| npm | vitest | 4.1.11 → 5.0.0 | `ts_core/package.json:37`, `web_ui/package.json:49` |
| npm | @vitest/coverage-v8 | 4.1.11 → 5.0.0 | `ts_core/package.json:33`, `web_ui/package.json:42` |
| npm | pnpm | 11.24.0 → 12.4.1 | `ts_core/package.json:12`, `web_ui/package.json:12` |
`very_good_analysis` keeps a caret by an explicit carve-out in
`rules/dependency-freshness.instructions.md` (SDK-coupled packages may keep a
range), but **its range floor is still checked** — `^10.3.0` fails because the
floor is behind latest. `^11.0.0` is the target, not a bare `11.0.0`.
`~/src/utils` is shared: 8 Flutter apps consume its Dart packages
(`home_inventory`, `kuhylog`, `lyricanki`, `punchme`, `todo`, `untools`,
`restaurant-rater`, `epopeja_karta`) and 4 TS repos consume `@kuhyx/ts-core` /
`@kuhyx/web-ui` (`europe-county-map`, `iron-and-anvil`,
`awesome-mcp-explorer`, `konbini-67`). Every one of those repos pins its own
`very_good_analysis`, so lint changes here are a preview of work they will
each need — **do not fix them in this session**, just note what you hit.
## Read first
- `rules/dependency-freshness.instructions.md` — the Dart caret carve-out, the
"range floor is still checked" rule, and **never `--no-verify`**.
- `dependency-freshness.allowlist.yaml` — ONE active entry (`npm:typescript`
pinned 6.0.3, `blocked_by: transitive:typescript-eslint@8.70.0`, held
fleet-wide). **Leave it alone.** TypeScript stays on 6.0.3 in both sessions.
- `design_system/analysis_options.yaml` — line 1 is
`include: package:very_good_analysis/analysis_options.yaml`, so the lint set
changes the moment the pin moves. The other three Dart packages follow the
same pattern.
## What `very_good_analysis 11` actually changes
Recorded when the fleet first hit this (2026-09-11), so expect these three
and confirm against the package's own changelog before assuming the list is
complete:
- `async_return_with_no_await` — **needs hand edits.** Not auto-fixable.
- `unnecessary_type_name_in_constructor` — `dart fix --apply` handles it.
- `unnecessary_const_in_enum_constructor` — `dart fix --apply` handles it.
For scale: in `betting-sim` the two auto-fixable rules alone hit 164 sites.
The four utils packages are much smaller, but run `dart fix --dry-run` first
so you know what you are about to change.
## Constraints you would otherwise rediscover painfully
- **pnpm only, never npm.** `@kuhyx/web-ui` is consumed as `&path:/web_ui`;
npm cannot install a monorepo subdirectory.
- **The pnpm 11 → 12 move is the riskiest item here.** Local pnpm is 11.26.0
and `corepack` is present at `~/.nvm/versions/node/v24.18.0/bin/corepack`.
The `packageManager` field carries a full `+sha512...` integrity hash —
regenerate it, do not hand-edit the hash. A past "Failed to switch pnpm to
vX" was a **stale shim in `$PNPM_HOME`**, not a pnpm bug; if you see it,
look for a stale binary on `PATH` and never delete `PNPM_HOME` itself.
- **`vitest 5` is a major** — check its migration notes for config and
coverage-provider changes before editing. `vitest` and
`@vitest/coverage-v8` must move together; a version-skewed pair fails at
coverage time, not at install time.
- **Coverage bars are not negotiable.** `scripts/check_coverage.sh` is the
adjudicator; if vitest 5 reports coverage differently, fix the config, do
not lower the bar.
- **No `# noqa` / `type: ignore` / per-file-ignores / lint disables** without
asking first, every time. All 7 "unavoidable" disables in a past konbini-67
session were reverted — exhaust refactors first.
- **250-line cap** on every file, enforced by `scripts/check_file_length.sh`.
- Heavy commands through `~/.claude/scripts/capped.sh`
(`CAP_MEM=4G CAP_CPU_PCT=20` to raise).
- Work on `main`; branching is hook-blocked. Stage narrowly.
## Procedure
Do these as **three separate commits**, in this order — each is independently
revertable, and mixing them makes a CI failure impossible to attribute.
**A. `very_good_analysis` → `^11.0.0`** (4 pubspecs)
1. Bump all four, then `flutter pub get` / `dart pub get` in each.
2. `dart fix --dry-run` in each; review, then `dart fix --apply`.
3. Hand-fix every `async_return_with_no_await` finding.
4. `flutter analyze` / `dart analyze` clean in all four.
5. Suites — all four are Flutter packages, so `flutter test` in each (not
`dart test`; only `crdt_sync_dart`, which this session does not touch, is
pure Dart): `crdt_sync_flutter`, `design_system`, `github_device_auth`,
`sync_settings_ui`.
**B. `vitest` + `@vitest/coverage-v8` → 5.0.0** (`ts_core`, `web_ui`)
1. Bump both packages in both manifests together. `pnpm install` in each.
2. `pnpm lint && pnpm test && pnpm coverage` in each.
3. If coverage reporting changed shape, fix the config so
`scripts/check_coverage.sh` still adjudicates — do not relax the bar.
**C. `pnpm` → 12.4.1** (`ts_core`, `web_ui`)
1. `corepack use pnpm@12.4.1` in each package so the `packageManager` field
and its integrity hash are regenerated, not hand-written.
2. `pnpm install` in each; commit the updated lockfiles.
3. `pnpm lint && pnpm test` in each.
4. Sanity-check one downstream consumer still resolves — e.g.
`cd ~/src/konbini-67 && pnpm install` — but **do not commit** in that repo.
After all three: `./scripts/check_dependency_freshness.sh --all` → **exit 0**
(the one `npm:typescript` allowlist entry will print as an active exception;
that is expected and is not a failure).
Then `pre-commit run --files <changed>` and push each commit with
`~/.claude/scripts/finish_auto.sh`, passing changed files explicitly.
## Exit condition
- `./scripts/check_dependency_freshness.sh --all` exits **0**, with only the
pre-existing `npm:typescript` exception reported.
- All four Dart packages analyze clean; `ts_core` and `web_ui` lint, test and
meet their coverage bars.
- No new allowlist entries, no new lint suppressions, `typescript` still 6.0.3.
- The **dependency freshness** workflow is green on `main` — the whole point;
it has been red since 2026-09-11.
- Delete this file (and `TODO-deps-01-*` if it is still present) in the final
commit.
## If a transitive conflict blocks a bump
Stop and ask, per conflict. Exact pins plus latest-everywhere is provably
unsatisfiable when a dependency internally constrains a shared transitive.
**Never auto-add an allowlist entry** — that is the user's call, and a
discretionary entry needs an `expires` date capped at 90 days.