refactor: address code-review findings on the containment fixes - #29
Open
steve-calvert-glean wants to merge 1 commit into
Open
refactor: address code-review findings on the containment fixes#29steve-calvert-glean wants to merge 1 commit into
steve-calvert-glean wants to merge 1 commit into
Conversation
Follow-up to #28. The Standards axis of the code review reported after that PR merged; these are its findings. No behaviour change — all 199 tests pass unchanged and each of #28's three reproductions was re-run and still resolves correctly. Duplicated Code, and the pointed one: listSourcePluginDirs was discoverSourcePlugins's scan loop copied verbatim — same exists guard, same readdir({withFileTypes}), same dotfile/non-dir skip, same isSourcePluginDir. Two copies of "what counts as a source plugin" drift, which is the bug class this whole review is about, and #28's own PR body claimed avoiding that duplication was the reason for putting the helper in config.ts. discoverSourcePlugins is now expressed over listSourcePluginDirs. Second instance: managed.ts's `pathsEqual(a, root) || isUnder(a, root)` was fs.ts's isInside plus folding. Replaced by one exported isInsideFolded beside isInside, which also removes a Mysterious Name — isUnder vs isInside gave no hint which one folded case. Data Clump: all three call sites passed project.rootDir, project.config, project.configPath, which is just ResolvedProjectConfig. buildDeleteGuard now takes (project, force), collapsing #28's sync->async ripple to one signature. Deliberately keeps taking the loaded config rather than discovery results, so clean still works when the source tree no longer loads. missing.reverse() was safe — it sat on the return line and the function exited immediately — but safety depended on a reader noticing the adjacent return. [...missing].reverse() costs nothing and removes the reasoning step. Comment style: dropped incident framing from two blocks, keeping the rationale. Co-Authored-By: Claude Opus 5 (1M context) <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.
Follow-up to #28, addressing the Standards axis of the code review — which reported after that PR merged rather than before. No behaviour change: all 199 tests pass unchanged, and each of #28's three original reproductions was re-run and still resolves correctly.
Duplicated Code — the pointed one
listSourcePluginDirswasdiscoverSourcePlugins's scan loop copied verbatim: sameexistsguard, samereaddir({ withFileTypes: true }), same dotfile/non-dir skip, sameisSourcePluginDircall. Two copies of "what counts as a source plugin" will drift — which is the bug class this entire 1.0 review is about, and #28's own PR body argued that avoiding that duplication was the reason for putting the helper inconfig.ts. It then duplicated the loop anyway.discoverSourcePluginsis now expressed overlistSourcePluginDirs, so there is one definition.Duplicated Code — second instance
managed.ts'spathsEqual(a, root) || isUnder(a, root)wasfs.ts'sisInsideplus folding. Replaced with one exportedisInsideFoldedbesideisInside. That also removes a Mysterious Name:isUndervsisInsidegave a reader no hint which of the two folded case.Data Clump
All three call sites passed
project.rootDir, project.config, project.configPath— which is exactlyResolvedProjectConfig.buildDeleteGuard(project, force)collapses #28's sync→async ripple to one signature.It deliberately still takes the loaded config rather than plugin-discovery results. The reviewer's stronger suggestion — derive the guard at load time, since
loadConfigalready discovered those directories — would couplecleanto a working build, andcleannot requiring one is load-bearing (it's often why someone is cleaning). The shallow readdir is the price of that independence.Smaller
missing.reverse()was safe — it sat on thereturnline and the function exited immediately — but the safety depended on a reader noticing the adjacentreturn.[...missing].reverse()costs nothing and removes the reasoning step.Still open from the review
The Spec axis never reported — two escalations, no output. And one question neither axis resolved: whether
main's existing testrefuses to clean the default source.plugins root even when unset in configstill asserts correct behaviour under the narrowed guard. My read is that it does, because its fixture'splugins/democontains askills/component dir and so is a genuine discovered source plugin — but I wrote both that test and the fix, so it's noted rather than closed.🤖 Generated with Claude Code