Make feature ordering non-load-bearing (and fix a real collision)#24
Merged
Conversation
…ision) Features merge their fragments in array order, so a collision between two of them was "resolved" silently by position — the exact fragility the architecture review flagged. Rather than build speculative phase/requires/conflictsWith machinery, this enforces the invariant that actually matters: no two features may own the same file or package.json field for a given config. test/feature-registry .test.js asserts unique feature ids and zero collisions across the full matrix (1683 configs), so a colliding new feature fails the test instead of shipping an order-dependent bug. That immediately surfaced a real one: on node-service, both `bundler` and `service` set scripts.dev, and only array order (service last) made the correct `tsx watch` win over `tsup --watch`. Fixed by making the service the explicit owner of its dev script — the bundler no longer contributes `dev` for a service target. Generated output is byte-identical (service won the merge before, owns it outright now); node-service is still 31 files with `dev: tsx watch src/index.ts`. 96 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.
Features merge their fragments in array order, so a collision between two of them was resolved silently by position — the fragility the architecture review flagged under "make feature ordering explicit."
The approach
Rather than build speculative
phase/requires/conflictsWithmachinery that nothing yet needs, this enforces the invariant that actually matters: no two features may own the same file orpackage.jsonfield for a given config.test/feature-registry.test.jsasserts unique feature ids and zero collisions across the full matrix (1683 configs), using the collision diagnostics the embedded API already computes. A colliding new feature now fails CI instead of shipping an order-dependent bug.It found a real one
On
node-service, bothbundlerandservicesetscripts.dev— and only array order (service listed last) made the correcttsx watch src/index.tswin over the bundler'stsup --watch. Reorder the registry and the service would silently get the wrong dev command.Fixed by making the service the explicit owner of its dev script; the bundler no longer contributes
devfor a service target.Output is byte-identical — the service won the merge before and owns it outright now.
node-serviceis still 31 files withdev: tsx watch src/index.ts. Also documented the ordering contract in the feature registry.96 tests pass (2 new), lint clean, web configurator verified.
🤖 Generated with Claude Code