Repository navigation
EPBDS-16211 H1: delete the dead weight, 26 files - #53
Merged
Merged
Conversation
§9.9-H1 has been "cheap, do first" since the plan was written. Doing it.
WHAT WENT
12 orphan components (src/core/components/): Avatar, Badge, Carousel,
Collapse, ErrorContent, ErrorTable, FloatNumber, ImageSwatch,
MenuButton, Square, TabList, Tags.
10 LESS files: the whole src/style/unused/ tree.
4 icomoon demo artifacts: demo.html, demo-files/, "Read Me.txt".
formatTime and toHours in src/core/utils/time.js, with the imports
that existed only for them.
WHAT DELIBERATELY STAYED
The ENGINE TabList (pages/main/components/TabList.js) — mapper.js:33
resolves it, and it is a different component from the pack copy: both
import './Tabs', and those two Tabs differ by ~100 lines. Swapping them
would have silently regressed tab behaviour.
The pack Tabs.js, so H6's duplicate pair is only HALF resolved.
icomoon's selection.json and style.css — selection.json is the project
file you re-upload to regenerate the icon set, the only round-trip path
back to it. Dead to every build, but its loss is not recoverable the way
the demo page's is.
FIELD.TYPE.DATE, which H1 also lists. Deleting it versus giving it a
`view: 'Date'` branch is an owners' decision, so it was left alone.
ONE DECISION THIS FORCED
ErrorTable could not go alone — ErrorContent imported it — and it was
also the last in-repo caller passing `inverted`/`striped` to Table.
SUPPORTED-PROPS.md said step 1 deferred their fate to exactly this
deletion. They are KEPT: both are genuinely styled
(table:not(.as-layout).inverted, table.striped tr:nth-child(2n)), Table.js
still destructures them, and a consumer meta can still set them. Dropping
a supported prop because our own last caller went away would be a
breaking change bought for nothing. The generated "Attributes at the call
sites" table no longer lists them, which is correct — that table reports
what the codebase passes, not what the component accepts — so
wrapper-prop-curation.js now says so in as many words.
VERIFIED BEFORE DELETING
One agent per target, each asked to REFUTE that its target was safe:
mapper registration, the components barrel, the published entry, every
import spelling, tracked metas, docs, schema, CSS, the sibling checkouts.
src/style/unused/ was cleared by compiling index.less through the repo's
own less-options and reading less's resolved import list (44 files, none
under unused/) rather than by grepping basenames.
MEASURED AFTER
suite 166 suites, 2539 -> 2527 tests. The -12 is exactly the two
time suites (-9, -3); no other suite's count moved.
coverage 94.83 -> 97.04 stmts, 90.19 -> 94.06 branch, 93.28 -> 96.88
funcs, 95.36 -> 97.76 lines. Thresholds green.
CSS static/all.css sha256 UNCHANGED at dcdb0a40a6d8ee79...
gates lint:js, lint:css, css:fixture:check, both docs checks,
build-lib, build-css all green.
SIDE EFFECTS WORTH NAMING
moment is now imported nowhere in src/core/utils/ — progress on §9.7-F2.
Workstream A loses 4 class components and 3 UNSAFE_* sites (29/14 -> 26/12).
The third function-component defaultProps site is resolved by deletion.
The plan is updated in the same commit: 28 places closed or corrected,
including the orphan counts, which are now a historical record rather than
a list of files to go looking for.
AlexSamBY
added a commit
that referenced
this pull request
Oct 2, 2026
## What changes **The checklists in `docs/UPGRADE-PLAN.md` now match what the plan records as done.** Several boxes were still open, or said "still open", after the work had landed and been recorded elsewhere in the plan. - Each box closed here cites the evidence that closes it. - Each box that stays open now says why. There is no code change. In `package.json`, only the text of lint messages changes. ### Closed, with the record that closes them **§9.3 step 3, de-globalizing instance state, is marked done.** - Its header read "STARTED 2026-09-23: `Active.translate` is done, the rest is not". - But every item under it had been closed or measured not to leak, and §11 retired R14 on that evidence (2026-10-01). **One item in step 3 had no record: the translation registries.** I checked them now, and there is nothing to convert: - Every `localiseTranslation` call in `src/core` runs at module top level. - `Active.LANG`, the language the phrases are read in, is assigned nowhere outside the tests. - The same search found no other write to `Active` from an instance, apart from the `translate` fallback that step 3 already records. `renderField`, `Field` and `UIRender` are code, and the same for every document. `passwordCheck` is set by the host. - Each zero-hit search was proven with a control: the same pattern run on the tests finds their writes. **Phase 6: five boxes are ticked.** - **State per instance:** §9.3 step 3 and R14, as above. - **Runtime hazards:** §9.3 step 4 records "This step is now empty", and R17 was retired on 2026-09-23. - **The engine ⇄ form-modules import cycle:** gone since #69 (2026-09-23). Re-checked: - No source file under `src/core/modules` imports the engine. Only its tests do, to render whole documents. - No suppression of the layer rule is left in `src`. - **Two instances on one page:** four tests cover it: `rules.two-instances.test.js`, `rules.two-instances-errors.test.js`, `popup-root.two-instances.test.js`, and the two-documents case in `examples.strict-mode.test.js`. - **StrictMode:** done 2026-09-29 (§9.3 step 7). The test has run on virtual time since #149. **The go/no-go on the E2/E3 tail of the TS migration.** It was decided GO on 2026-09-30 (§9.6, Governance), and the tail is done. **H1/H6: the pack `Tabs`.** - #60 (2026-09-22) renamed it `StandaloneTabs`, because the two copies are not interchangeable. - Its one importer is the demo's `NavTabs`. - `view: 'Tabs'` renders the engine's copy. **H1/H6: grepping consumer metas for orphan names is moot, as measured.** - The mapper registered none of the twelve component files that #53 deleted. - Eleven of the names were never views. Each renders the same "… field does not exist!" placeholder on the commit before #53 and on master. - The twelfth, `TabList`, resolves to the engine's copy on both. - So whatever a consumer's metas contain, the deletion changed nothing they render. **Phase 1: the react-refresh dev loop, checked on 18.** - The demo has developed against React 18.3 since #31, and the checkpoint release on 17 was cancelled (§10). So there is no dev loop on 17 left to check. - In the running demo, an edit to `src/demo/pages/Examples.jsx` arrived as a hot update, and so did reverting it. - Neither reloaded the page: a value set on `window` survived both, and so did a number typed into a field. **Ongoing invariant: the alias grep stays at zero.** - It reads 0 today. - No `ui-*-pack` alias is configured in any webpack config or in jest, and no such package is installed. So an import of one fails to resolve. **Two findings are marked resolved.** - **E3's `colGroup` propType:** E5 deleted the propTypes, and the TS type, `TableColGroupProps['colGroup']`, says `style`. - **F1's tooltip half:** closed at F1 step 2. `omitProps` keeps `view`, `index` and `symbol` off the bubble. ### Left open, now saying why - **F2:** "The gate did not open: `moment` stays (2026-09-30)". Its two boxes wait for a reopening. The F2-seam invariant now says it applies only if F2 reopens. - **F4:** postponed on 2026-09-30, and no longer a React 19 prerequisite. Its two boxes stay open. ### `package.json`: the layer lint's messages Only the message text changes, in 14 messages: - **The `core/modules` message** said "Two sites in modules/form/utils.tsx predate this rule and carry an eslint-disable". #69 (§9.3 step 2) removed both. - **The `core/state` override's three messages** began "core/utils must not import". They were copied from the utils override. - **The layer direction every message quotes left out `core/state`.** It now matches CLAUDE.md, and the bans configured in the overrides. I put a probe import of the engine in `src/core/state` and another in `src/core/modules`. Both still fail lint, with the new text, and the probes are removed. Rewriting `package.json` through JSON leaves it byte-identical when nothing is changed, so nothing but these 14 lines moved. ## Gates All exited 0, run on this branch: - `lint:js`, `lint:css`, `typecheck`, `typecheck:contract`; - `docs:props:check`, `docs:views:check`, `css:fixture:check`; - `test:env-flags`, `build`; - `test:coverage`, thresholds included; - `test:pack`, `test:pack:peers`, `test:types`; - `test:react16`, `test:react17`, `test:react19`, 2854 tests each, with no worker crash; - `test:e2e`, 41 tests; - the manifest contract. The number of tests is unchanged. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
AlexSamBY
added a commit
that referenced
this pull request
Oct 9, 2026
…s at what is measured, and the plan's stale lines (#203) ## What The process half of the 2026-10-08 audit: lint for the code nobody linted, a gate against focused tests, coverage thresholds at what the suite covers, and the plan's stale lines. ### Lint covers the tooling `npm run lint:js` now runs over `scripts/`, `e2e/` and the config files at the root, as well as `src`. That is 63 more files, under `eslint-config-react-app`'s rules without the React, JSX and hooks ones (`TOOLING_RULES` in `eslint.config.js`). Each file gets the node, browser or jest globals of the place it runs. The first run found 16 problems: - **Fixed, 11.** - Seven unused names in the browser specs: five imports (`DISMISSAL`, `TOUCH`, `tooltipA11yWiring`, `topmostAt`, `BUBBLE`), and two `bubble` helpers nothing called. Their `BUBBLE` imports went with them. - `scripts/jest-console-guard.js` reassigned its buffer under a function created in a loop (`no-loop-func`). The buffer is now a constant array cleared in place, with the same behaviour. - The two webpack configs export a named value (`import/no-anonymous-default-export`). - A `/* global globalThis */` redeclared a built-in, and is gone. - **Configuration, 4.** - `document` was undefined in `scripts/fixtures/packed-browser-entry.js`, which runs in a page; that file has browser globals now. - The hooks rules read a Playwright fixture's `use` as React's `use`; they are not applied to the tooling. - **Suppressed, 1.** A string of prose in `scripts/wrapper-prop-curation.js` names the `${id}-help` template. The suppression states that reason. ### A focused test fails lint The ban covers `it.only`, `describe.only`, `test.only`, `test.describe.only`, `test.concurrent.only`, `.only.each`, `fit` and `fdescribe`. It applies in `src/**/__tests__`, `scripts/__tests__`, `e2e/**/*.pw.js` and `e2e/**/*.packed.js`. A focused test runs alone: the rest of its file is skipped, and the run still passes. Jest has no `--forbid-only`, and Playwright's `forbidOnly` is set for CI only. `eslint-plugin-jest` is not installed, so the gate uses two core rules: `no-restricted-properties` on `.only` and `no-restricted-globals` on `fit`/`fdescribe`. ### Coverage thresholds at what the suite measures Each threshold is the measured value, rounded down to a whole percent (statements/branches/functions/lines): - global: 89/79/85/90 → **98/95/97/99**; - `rules.tsx`: 89/76/98/91 → **96/87/100/98**; - ten more entries rise by 1 to 3 points; - `function.ts` goes 96 → 100 on branches and 75 → 80 on functions, and its comment says why; - six files get entries of their own: `documentHost.ts`, `formData.ts`, `errorMapping.ts`, `dataMapping.ts`, `popupScope.ts` and `lodash-lite.ts`. `jest.config.js` states the rule above the block: a change that covers less either covers what it adds or lowers the number in the same commit, saying why. ### The plan's stale lines 13 lines in `docs/UPGRADE-PLAN.md` changed, each one in place, with a date and the evidence: - **Sequencing (§6, §9.3, §9.9).** "Never mix an upgrade with a refactor in one release" is recorded as not held. Nothing has been released since Phase 2 (the last tag is v0.34.3, 2026-08-12), and §9.2's hooks migration and §9.3's decomposition landed after it. §9.3's "do not start" and §9.9's sequencing get the dates the work was done. - **§9.3 step 2.** "STARTED" and "Still to extract" now name what §9.3 closed without extracting: `transformConfig`/`toOpenLConfig` and `initSelectStatesFromData`, still in `rules.tsx`. - **R8.** `javascriptEnabled` went on 2026-10-08, and `size()`/`px()` are called at 133 sites, not 186. - **R10.** The audit and the prop list are done. The owners' MINOR call overruled "anything dropped ⇒ major", and the migration notes are in the changelog. - **Appendix B.** The `npm audit` baseline was 0 on 2026-09-30 and 35 on 2026-10-06, and has not been re-measured since. The line also says why the `"prop-types":` pattern has a colon. - **Appendix C.** - The upstream form-stack line is qualified by F4's finding. - There are two `cloneElement` sites, not one. - `prop-types` is retired. - The React 19 box no longer contradicts itself. ## Measured - **Lint.** 445 files, 0 problems: 382 in `src` and 63 in the tooling. Master's versions of five of the fixed files each fail the new configuration, with the rule named. - **Focused tests.** A probe with nine focused forms was linted as a file in each of the three test locations. All nine are reported in each; `describe.skip` is not, and neither is `.only` outside a test file. - **The open PRs.** - Under this configuration, #200's and #201's changed tooling and test files lint clean. - #202's one finding is the unused `BUBBLE` this PR removes, in a different hunk of the same file. - **Coverage.** - Two runs, one in the local time zone and one in UTC as on CI, were identical on every file and metric (214 suites, 2776 tests). - The thresholds are the lower of the two, rounded down. - **Local gates, all exit 0.** That covers all 21 gates plus the manifest contract, on Node 24.14.0: - lint and types: `lint:js`, `lint:css`, `typecheck`, `typecheck:contract`; - generated files: `docs:props:check`, `docs:views:check`, `css:fixture:check`, `build-css:check`; - builds and jest: `test:env-flags`, `test:coverage`, `build`, `test:react16`, `test:react17`, `test:react19`; - packaging: `test:pack`, `test:css:built`, `test:pack:peers`, `test:types`, `test:pack:browser`; - browser: `test:e2e`, `test:e2e:react19`. They ran on this commit's tree before two wording fixes, one in a comment in `eslint.config.js` and one in the changelog entry. After those, `lint:js` was rerun, along with the two suites that read those files (`wrapper-prop-reference.contract.test.js`, `NavTabs.history.test.js`), all exit 0. - **Against the open PRs.** `git merge-tree` merges this commit cleanly with #200, #201 and #202. The file this PR and #202 both change, `e2e/keyboard-a11y.pw.js`, lints clean once merged. ## Left for the owners GitHub holds eight branches; merged PR branches are deleted on merge. Besides `master`, `gh-pages` and the three open PRs' branches, three remain: - `main`: a 2021 initial commit holding only `LICENSE`, outside master's history. - `h1-dead-weight`: PR #52 was closed unmerged, and its content merged as #53 from `h1-dead-weight-rebased`. - `release/v0.34`: the 0.34 patch line §10 names. It carries two commits outside master's history (#27 and v0.34.3, 2026-08-12) and has no workflows. Whether to delete the first two, and whether the third gets CI or a statement that 0.34 takes no more fixes, is not decided here. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.
Replaces #52, which conflicted after #51 was squash-merged: this is the same single H1 commit, rebased onto
master. Identical diff — 32 files, +61 −3150.What went
Avatar,Badge,Carousel,Collapse,ErrorContent,ErrorTable,FloatNumber,ImageSwatch,MenuButton,Square,TabList,Tagssrc/style/unused/treedemo.html,demo-files/,Read Me.txtformatTime,toHoursintime.js, with the imports that existed only for themWhat deliberately stayed
The engine
TabList(pages/main/components/TabList.js) —mapper.js:33resolves it, and it is not interchangeable with the pack copy: bothimport './Tabs', and those twoTabsdiffer by ~100 lines. Swapping them would have silently regressed tab behaviour. The packTabs.jsalso stays, so H6's duplicate pair is only half resolved.icomoon's
selection.jsonandstyle.css—selection.jsonis the project file you re-upload to regenerate the icon set, the only round-trip path back to it. Dead to every build, but its loss is not recoverable the way a demo page's is.FIELD.TYPE.DATE, which H1 also lists — delete it, or give it aview: 'Date'branch? That is an owners' call, so it was left alone.One decision this forced
ErrorTablecould not go alone (ErrorContentimported it), and it was also the last in-repo caller passinginverted/stripedtoTable.SUPPORTED-PROPS.mdrecorded that step 1 deferred their fate to exactly this deletion.They are kept. Both are genuinely styled (
table:not(.as-layout).inverted,table.striped tr:nth-child(2n)),Table.jsstill destructures them, and a consumer meta can still set them. Dropping a supported prop because our own last caller went away would be a breaking change bought for nothing. The generated "Attributes at the call sites" table no longer lists them — which is correct, since that table reports what the codebase passes, not what the component accepts — sowrapper-prop-curation.jsnow says so explicitly.Verified before deleting
One agent per target, each asked to refute that its target was safe: mapper registration, the components barrel, the published entry, every import spelling, tracked metas, docs, schema, CSS, the sibling checkouts.
src/style/unused/was cleared by compilingindex.lessthrough the repo's ownless-optionsand reading less's resolved import list (44 files, none underunused/) — not by grepping basenames, which would have been wrong here:avatar.lessandcarousel.lessexist elsewhere too.Measured after
The −12 tests are exactly the two time suites (−9, −3); a per-suite diff confirms no other suite's count moved. Coverage thresholds green.
static/all.csssha256 unchanged atdcdb0a40a6d8ee79…— deletingunused/and the icomoon page touched no byte a consumer downloads.lint:js,lint:css,css:fixture:check, both docs checks,build-libandbuild-cssall green.Side effects worth naming
momentis now imported nowhere insrc/core/utils/— progress on §9.7-F2.UNSAFE_*sites (29/14 → 26/12, re-measured).defaultPropssite is resolved by deletion.The plan is updated in the same commit — 28 places closed or corrected, including the orphan counts, which are now a historical record rather than a list of files to go looking for.
🤖 Generated with Claude Code