chore(desktop): admit validated copy catalogs in the renderer architecture ratchet - #4493
Conversation
The locale policy forces user-visible copy out of business files and into locales/ catalogs, which adds import edges the renderer architecture ratchet forbids in legacy files — the two gates deadlock. Admit exactly one dependency class: a structurally validated copy catalog (UiCatalog marker, zero tracked capabilities, bare package imports only), re-verified on every run so a catalog can never become a dependency tunnel. Root-entry import and token ratchets stay strict.
Astro-Han
left a comment
There was a problem hiding this comment.
Verified the load-bearing claims on da6662a9: validation re-runs from the working tree on every check (no grandfathering), the bare-specifier rule is equivalent to resolveDependency's two prefixes, root-entry metrics still ratchet, and the stale-budget check forces the ledger deletion. Approving; two things worth settling before this shapes the next PRs.
The catalog predicate is brittle, and the ledger deletion is a one-way door. The predicate reuses environmentCapabilities, which treats any unshadowed identifier in ENVIRONMENT_OBJECTS as a global. I ran analyzeRendererSource from this head against the head catalogs: settings-data-copy.ts reports {history: 3} — that's the copy key history: '输入历史' — and settings-test-result-copy.ts reports {location: 1} from a parameter name. Three more (onboarding-copy, settings-navigation-copy, settings-projects-copy) fail the bare-specifier rule on type-only imports from src/shared/src/preload. None of those five currently carry deleted budget edges, so CI is green — but once a future change gives shell-copy.ts (10 deleted edges) or conversation-copy.ts (8) a key named history or a type-only relative import, the catalog silently drops out, the feature edges come back as unbudgeted, and re-adding them to the ledger hits new feature-to-legacy imports are forbidden. Nothing in the violation text says "this catalog stopped validating". Any of these would close it: exclude object keys/parameters from the catalog check (or use a narrower "no behavior" predicate than environmentCapabilities), allow type-only imports that resolve outside src/renderer, or at minimum emit a dedicated violation when a *-copy.ts under locales/ fails validation.
The #4457 framing doesn't match its log. Run 33500504864 has 25 violations; 13 are expected-operation-error.ts being a new renderer root module (10 dependency-debt edges, closure entry, unclassified file, feature import), which this PR doesn't touch. It clears 2. And #4457's shell-copy.ts imports ../expected-operation-error.js, which fails the new predicate — so on top of this PR, #4457 gains roughly 18 unfixable violations rather than losing 14. Worth rewriting the description to what this PR actually admits, and coordinating with #4457 (move expected-operation-error out of src/renderer/, or reach the work-board-ipc types through a bare specifier).
Minor: README says "never renderer implementation", but the rule rejects src/shared/src/preload type imports too; no fixture for the @maka/desktop/ prefix or the unresolvedDependencies case; the ledger drops 25 edges, not 26.
The catalog predicate inherited analyzer false positives (object keys and type-space identifiers counted as environment globals) and rejected type-only relative imports, so a catalog could silently lose admission. Count only value references, restrict the bare-specifier rule to runtime imports, and report failed catalogs with a dedicated violation.
Updated in the next revision |
|
@Astro-Han CI is all green |
|
@Astro-Han Can we merge this? It will unblock my other refactor PRs. Thank you! |
Part of #2672
Two repository gates deadlock. The locale policy (#2672, enforced by the copy-gate family) forces user-visible copy OUT of business files and INTO
src/renderer/locales/*-copy.tscatalogs — which necessarily ADDS an import edge. The renderer architecture ratchet forbids exactly that: legacy files may not grow their dependency count at all, and the AppShell closure rejects any new entry. #4457 fails CI on precisely this collision (12 ×new dependency debt, 2 ×new legacyAppShellClosure debt entries are forbidden); no placement of the catalog can satisfy both gates today.This PR admits exactly one dependency class instead of loosening the ratchet generally. A "validated copy catalog" is recognized structurally and re-verified on every checker run — never grandfathered:
src/renderer/locales/*-copy.ts;UiCatalogmarker imported from@maka/core/ui-locale(satisfiesor type annotation);@maka/desktop/imports — so a catalog can never become a tunnel to renderer implementation.Admitted edges are excluded from the dependency-count ratchets and closure admission, and feature/Desktop-adapter imports of a validated catalog need no legacy budget edge (the ledger drops 26 now-unneeded budget entries). Everything else still ratchets: the importing file's hook/bridge/environment/token rules are untouched, root-entry (
app-shell.tsxfamily) import and token counts stay strict, and a catalog that grows a hook or a relative import instantly loses admission — the adversarial fixtures cover hook smuggling, implementation-import smuggling, a missing marker, dynamic imports (fail closed upstream), and an unrelated dependency added beside a valid catalog.Boundaries: root-entry files deliberately get no import-count discount — touching
app-shell.tsxstill requires net-zero there. Documented insrc/renderer/README.md.AI use
Select exactly one:
Tool(s) and scope: Codex implemented the revision propagation and causal overlay retirement, added regression tests, and assisted with review. All affected commits include
Generated-by: Codextrailers.