Grouped resolved config view + prove derived state is consistent#26
Merged
Conversation
…stent The config carries ~16 derived flags (isTs, hasApp, publishable, isReact, usesVite…). The review's worry was that they can in principle contradict. Two changes address that: - normalizeConfig now attaches cfg.resolved — a grouped, read-only view of the same booleans, organized by concern (targets/language/framework/ build/module/package). Consumers can read structured state instead of re-interpreting raw selections; deriveDeploymentContract now does. - test/invariants.test.js proves the derived state can't silently contradict itself. Across a broad matrix it asserts the grouped view never disagrees with the flat flags, and that the state is internally consistent: publishable exactly matches its definition, an app is always ESM and never publishable, a service is never publishable, at most one framework, and every gated option (pkgChecks/sizeLimit/sourcemaps/ storybook/e2e/jsr/canary) is off when its precondition fails. cfg.resolved is config-only — never emitted, and excluded from provenance, serialization, and the digest — so output and reproducibility are unaffected. Deliberately NOT done: mechanically rewriting every cfg.hasApp reference across the features to cfg.resolved.targets.app. It's byte-safe but pure cosmetic churn with no functional gain; the flat flags stay supported and the invariants test guarantees the two never drift. 99 tests pass (2 new), lint clean, web configurator verified. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
The config carries ~16 derived flags (
isTs,hasApp,publishable,isReact,usesVite…). The architecture review's worry was that they can in principle contradict each other. Two changes address that — and I made a deliberate scope call on a third.Structured view
normalizeConfignow attachescfg.resolved— a grouped, read-only view of the same booleans, organized by concern:Consumers that prefer structured access read
cfg.resolved.targets.appinstead of re-interpreting raw selections.deriveDeploymentContractnow does, as the reference pattern.Proof it can't contradict
test/invariants.test.jsis the real answer to "flags can contradict." Across a broad matrix it asserts:publishableexactly matches its definition, an app is always ESM and never publishable, a service is never publishable, at most one framework is active, and every gated option (pkgChecks/sizeLimit/sourcemaps/storybook/e2e/jsr/canary) is off when its precondition fails.A future
normalizeConfigchange that introduces a contradiction fails here.cfg.resolvedis config-only — never emitted, and excluded from provenance, serialization, and the digest — so output and reproducibility are unaffected.Deliberately not done
Mechanically rewriting every
cfg.hasAppacross the features tocfg.resolved.targets.app. It's byte-safe but pure cosmetic churn with zero functional gain; the flat flags stay supported and the invariants test guarantees the two never drift. Flagging the judgment call rather than burning a 300-site diff.99 tests pass (2 new), lint clean, web configurator verified.
🤖 Generated with Claude Code