mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-11 12:47:44 +01:00
unified-design-system: record the two extractions this pass shipped
`ts_core` (@kuhyx/ts-core) and `github_device_auth` close the two clusters
the audit flagged as genuinely missed. Six shared packages now, not four.
Both extractions turned up the same lesson, worth writing down: the copy
that looks canonical is not always the one to take. Each cluster had a
behaviour living in exactly one repo that a naive "extract the tidiest
version" would have silently deleted --
* diet-guard's configurable device-flow endpoints, without which its
desktop web build cannot authenticate at all (no CORS headers on
GitHub's endpoints)
* wake-alarm's transient-socket retry, without which an approved grant
is lost if GitHub closes the connection at the wrong moment
Both are now in the shared package, so all four apps gained the fix the
other three never had. Same shape in ts_core: the RNG ships two interfaces
rather than one reconciled shape, because the generated sequence is the
contract and re-rolling every saved world would be a worse outcome than
the duplication.
sims3-clone is recorded as the one consumer still pending -- another
session had uncommitted work there, so migrating it would have entangled
two sets of changes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U4Rj3s7K2qzrLNgJqqPhno
This commit is contained in:
parent
254e3b00c7
commit
682eaf6f8c
@ -4,15 +4,19 @@ Answers "are all the components we actually use extracted?" across all three
|
|||||||
shared packages, after Phases 1–3 shipped. Companion to `nielsen-audit.md`
|
shared packages, after Phases 1–3 shipped. Companion to `nielsen-audit.md`
|
||||||
(the grid) and `phase3-record.md` (Phase 3's verdicts).
|
(the grid) and `phase3-record.md` (Phase 3's verdicts).
|
||||||
|
|
||||||
**Short answer: yes, with one leftover — now fixed — and one clear miss.**
|
**Short answer: everything is extracted now.** The audit found one leftover
|
||||||
|
donor copy and two genuinely-missed clusters; all three were resolved on
|
||||||
|
2026-08-15. The pre-existing extractions held up — no shipped component was a
|
||||||
|
false positive.
|
||||||
|
|
||||||
The three packages' extractions hold up. No shipped component turned out to be
|
One repo is outstanding: **sims3-clone** still has its own RNG copy, skipped
|
||||||
a false positive, and the reverse check (did the donor copies actually get
|
because another session had uncommitted work in it.
|
||||||
deleted?) is clean except for one case.
|
|
||||||
|
|
||||||
## There is a fourth shared package
|
## There is a fourth shared package
|
||||||
|
|
||||||
The phase briefs name three. There are four:
|
The phase briefs name three. There were four; this pass added two more, so
|
||||||
|
there are now six — one per stack per concern, all in the `kuhyx/utils`
|
||||||
|
monorepo:
|
||||||
|
|
||||||
| Package | Stack | Consumers |
|
| Package | Stack | Consumers |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
@ -20,6 +24,8 @@ The phase briefs name three. There are four:
|
|||||||
| `gatelock` | Python/Tk | 4 guard apps (2 bumped) |
|
| `gatelock` | Python/Tk | 4 guard apps (2 bumped) |
|
||||||
| `web_ui` | TS/React | dufs-cloud, awesome-mcp-explorer |
|
| `web_ui` | TS/React | dufs-cloud, awesome-mcp-explorer |
|
||||||
| **`sync_settings_ui`** | Dart/Flutter | todo, home_inventory, diet-guard, wake-alarm |
|
| **`sync_settings_ui`** | Dart/Flutter | todo, home_inventory, diet-guard, wake-alarm |
|
||||||
|
| `ts_core` *(new)* | TS, framework-free | konbini-67, iron-and-anvil, europe-county-map |
|
||||||
|
| `github_device_auth` *(new)* | Dart/Flutter | todo, home_inventory, diet-guard, wake-alarm |
|
||||||
|
|
||||||
`sync_settings_ui` (`backup_slot.dart`, `firebase_sync_controller.dart`,
|
`sync_settings_ui` (`backup_slot.dart`, `firebase_sync_controller.dart`,
|
||||||
`sync_settings_screen.dart`) changes the coverage answer for the whole sync
|
`sync_settings_screen.dart`) changes the coverage answer for the whole sync
|
||||||
@ -38,48 +44,80 @@ The union shipped; this donor was never deleted. Retired in
|
|||||||
|
|
||||||
(untools' `_SectionHeading`, the other named donor, *was* correctly deleted.)
|
(untools' `_SectionHeading`, the other named donor, *was* correctly deleted.)
|
||||||
|
|
||||||
## The one clear miss — `DeviceCodeDialog` ×3
|
## RESOLVED — `DeviceCodeDialog` + `GitHubDeviceAuth` ×4
|
||||||
|
|
||||||
The strongest finding. A modal showing a GitHub device-flow user code:
|
**Extracted 2026-08-15** into `~/utils/github_device_auth` (v0.3.0). All four
|
||||||
copies to clipboard, launches the verification URL, polls for the token,
|
apps migrated, local copies deleted, all four suites green, all four release
|
||||||
pops with it or renders an error.
|
APKs installed on the phone.
|
||||||
|
|
||||||
| Repo | Path | Lines |
|
The extraction found two real behaviours that existed in only one copy each,
|
||||||
|
and would have been *deleted* by a naive "take the canonical one" extraction:
|
||||||
|
|
||||||
|
- **diet-guard**: configurable `deviceCodeUrl`/`tokenUrl`. Its desktop web
|
||||||
|
build must route through a local CORS proxy, because GitHub's device-flow
|
||||||
|
endpoints send no CORS headers. Verified by `flutter build web` passing.
|
||||||
|
- **wake-alarm**: transient-network retry in `pollForToken`. GitHub can close
|
||||||
|
the connection at the moment the user authorizes; without the retry an
|
||||||
|
approved grant is lost.
|
||||||
|
|
||||||
|
Both are now in the shared package, so all four apps have both. Plus one bug
|
||||||
|
fixed for everyone: the dialog caught `on Exception`, which misses
|
||||||
|
`ArgumentError` and leaves it spinning forever — the same trap that killed
|
||||||
|
the Firebase sync tick in 2026-08.
|
||||||
|
|
||||||
|
**Lesson for the next extraction:** "byte-identical" applied to the *dialogs*,
|
||||||
|
not the *clients*. Diff every copy before picking a donor; the odd one out may
|
||||||
|
be the one that learned something.
|
||||||
|
|
||||||
|
## What the four GitHub copies looked like (historical)
|
||||||
|
|
||||||
|
| Repo | Client | Dialog |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| todo | `lib/ui/device_code_dialog.dart` | 110 (public) |
|
| todo | `lib/sync/github_device_auth.dart` (154) | `lib/ui/device_code_dialog.dart` (110, public) |
|
||||||
| wake-alarm | `phone_app/lib/screens/github_mirror_screen.dart:157-240` | ~84 (private) |
|
| home_inventory | same file, **byte-identical** (154) | — |
|
||||||
| diet-guard | `app/lib/screens/github_mirror_screen.dart:398-481` | ~84 (private) |
|
| diet-guard | `app/lib/services/…` (175, configurable URLs) | inline (~84) |
|
||||||
|
| wake-alarm | `phone_app/lib/services/…` (166, socket retry) | inline (~84, **byte-identical** to diet-guard's) |
|
||||||
|
|
||||||
**The wake-alarm and diet-guard copies are byte-for-byte identical** (`diff`
|
`GitHubMirrorScreen` ×4 itself stays app-local — each copy carries the
|
||||||
returns empty). todo's differs only by being public/keyed with doc comments.
|
"connecting here also triggers an actual sync" comment. Only the leaf
|
||||||
Same domain types (`DeviceCodeResponse`, `GitHubDeviceAuth`), same props, same
|
extracted.
|
||||||
`String? _error` state, same `initState`→`_poll` lifecycle.
|
|
||||||
|
|
||||||
**Belongs in `sync_settings_ui`, not `design_system`** — it depends on GitHub
|
## RESOLVED — `Clock` + mulberry32 RNG
|
||||||
auth types, so it is not a generic widget. Not yet extracted.
|
|
||||||
|
|
||||||
Note this is a *leaf* of the `GitHubMirrorScreen` ×4 cluster, which is
|
**Extracted 2026-08-15** into `~/utils/ts_core` (`@kuhyx/ts-core` v0.1.0).
|
||||||
deliberately app-local (each copy carries the "connecting here also triggers
|
konbini-67, iron-and-anvil and europe-county-map migrated; all three green.
|
||||||
an actual sync" comment). The screen stays local; the dialog need not.
|
|
||||||
|
|
||||||
## True duplicates outside every package's remit
|
Deliberately its own package, not part of `web_ui`: that ships `tokens.css`
|
||||||
|
and React components, and making a game install a UI package to get a seeded
|
||||||
|
RNG is the coupling that causes vendoring in the first place.
|
||||||
|
|
||||||
Real duplication, but none of it is UI, so no existing package owns it.
|
The RNG exports **two** interfaces rather than one reconciled shape, because
|
||||||
**These are not a reason to widen `web_ui`'s remit** — it is a UI package, and
|
the *sequence* is the contract — these repos guarantee "same seed → identical
|
||||||
the games were explicitly out of Phase 3 scope. A separate shared utility
|
world", so changing how many times a helper advances the generator re-rolls
|
||||||
module would be the vehicle, in a future phase.
|
every saved world. konbini-67 additionally keeps a local exclusive-max
|
||||||
|
`nextInt` adapter, verified identical over 10,500 draws.
|
||||||
|
|
||||||
|
`hotline3d` is deliberately NOT a consumer: its generator uses `%`/`Math.trunc`
|
||||||
|
where mulberry32 uses `>>>`, and measurably emits a different sequence.
|
||||||
|
|
||||||
|
**This forced all four game repos from npm to pnpm** — npm cannot install a
|
||||||
|
subdirectory of a git repo, so an npm repo is structurally locked out of every
|
||||||
|
shared package in this monorepo. sims3-clone is the one repo still pending:
|
||||||
|
another session had uncommitted work in it.
|
||||||
|
|
||||||
|
## Remaining true duplicates outside every package's remit
|
||||||
|
|
||||||
|
What is left after this pass. Neither is UI, so `web_ui` is still the wrong
|
||||||
|
home for both — `ts_core` took the TypeScript utilities, and the Dart one
|
||||||
|
belongs to `crdt_sync_dart`.
|
||||||
|
|
||||||
- **`_PrefsPersistence` ×3** — todo, home_inventory, diet-guard, all
|
- **`_PrefsPersistence` ×3** — todo, home_inventory, diet-guard, all
|
||||||
`implements LogPersistence`, all at the identical line number. Belongs to
|
`implements LogPersistence`, all at the identical line number. Belongs to
|
||||||
`crdt_sync_dart`'s remit.
|
`crdt_sync_dart`'s remit.
|
||||||
- **`Clock` / `createRealClock` / `createManualClock` ×2** — konbini-67 (59
|
- **mulberry32 RNG in `sims3-clone`** — the one consumer not yet migrated to
|
||||||
lines) and iron-and-anvil (49). Same interface, same `realClock` shared
|
`@kuhyx/ts-core`, skipped because another session had uncommitted work in
|
||||||
instance with the same rationale, doc comments near-verbatim.
|
that repo. Its interface (`next`/`int`/`pick`) maps onto `createSeededRng`
|
||||||
- **mulberry32 seeded RNG ×4** — konbini-67, sims3-clone, europe-county-map,
|
directly; the migration is a seam file plus an npm→pnpm move.
|
||||||
hotline3d. Identical `0x6d2b79f5` core in all four, but the *interfaces*
|
|
||||||
genuinely differ (closure-returning-methods vs mutable-state-plus-free-
|
|
||||||
functions; `float`/`next` naming; `chance` in only one). Extractable, but
|
|
||||||
it is an API reconciliation, not a lift-and-shift.
|
|
||||||
|
|
||||||
## Correctly not extracted (name collisions)
|
## Correctly not extracted (name collisions)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user