fix: allow identical copyPackFile source across components#325
Merged
fix: allow identical copyPackFile source across components#325
Conversation
- Treat same-source duplicate (destination, fileType) as identity, not conflict - Unblocks one hook script registered against multiple hook events - Add test for two hook components sharing source and destination
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.
Summary
PR #320 introduced intra-pack duplicate-destination validation that incorrectly rejected a legitimate pattern: one physical hook script registered against multiple hook events. Because
hookEventis singular per component, authors must declare N components — all copying the same source to the same destination — which is an identity, not a collision. This PR tightens the validator so it only throws when sources actually differ.Changes
ExternalPackManifest.validate()now tracks(componentID, source)per destination group. For groups with more than one entry, anallSatisfycheck collapses the identity case (every entry copies the same source → benign, skipped). Real conflicts (distinct sources for the same destination) still throwManifestError.duplicateDestination."generic"string fallback withExternalCopyFileType.generic.rawValueto drop the stringly-typed literal.allowSameSourceDestinationAcrossHookEventstest covering two hook components sharing bothsourceanddestination. ExistingrejectDuplicate*tests still cover the real-collision branch.Context
Real-world hit: the
mcs-memorypack declareshook-sync-memories(SessionStart) andhook-reindex-memories(UserPromptSubmit), both copyinghooks/sync-memories.sh→sync-memories.sh. After PR #320,mcs sync --globalwarned:This is the same file being registered against two hook events, not two files fighting for one destination. The validator should only catch the latter.
A more architecturally elegant alternative — letting
hookEventaccept an array so one component registers for multiple events — was considered but deferred. That change ripples through ~13 files (HookRegistration.event, encoder/decoder, sync strategies,PackArtifactRecord.hookCommands, doctor checks, export/discovery, collision resolver) and deserves its own PR.ExternalCopyPackFileConfighas exactly three fields (source,destination,fileType?) with no hidden mode/permissions/ownership, sosourceequality is a complete identity check.Test plan
swift test --filter MCSTests.ExternalPackManifestTests— 92/92 passswift test— 978/978 passswiftformat --lint .andswiftlintpass without violationsswift run mcs pack validate ~/Developer/mcs-memory→[OK] memory — all checks passedrejectDuplicateCopyPackFileDestinations,rejectDuplicateGenericFileTypeDestinations) still reject the real-collision branchChecklist for engine changes
ExternalPackManifestTests; integration lifecycle is unchanged (validator is the only touched path)