Scope preflight override to owned commands - #36
Conversation
registerPreflight used the bare-function form, which the pm runtime treats as a global override. Two globally-scoped overrides genuinely contend: pm health reports extension_preflight_override_collision for every installed pair, so all six fleet packages installed together produce 15 warnings and ok: false. Rewrite the registration to the scoped object form, declaring exactly the mutating github/gh-issues command paths the override guards. The runtime matches a command against the commands array by exact normalized path, so the array must list the full command paths (github sync, github export, github import, gh-issues import, github project import, github project sync) rather than a bare top-level name: a bare 'github' never matches 'github sync' and would silently disable the early warning. The authoritative credential gate stays in the command handlers; this only narrows the override's scope so it no longer contends with other packages' overrides. Verified: with two of these packages installed, pm health reported ok: false with one collision warning; after scoping both, ok: true with zero warnings and the guarded command still runs.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
Summary by CodeRabbit
WalkthroughThe GitHub preflight registration now uses a scoped object for six pm-github mutating command paths. The smoke test verifies the scope and callable runner. The changelog and project records document the completed fix. ChangesScoped pm-github preflight
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to The change narrows the preflight override to the commands it owns, preventing false collision warnings without changing the authoritative credential checks; no actionable merge-blocking risk remains after normal checks and review. Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Reviewer's GuideScopes the pm-github extension’s preflight override to the exact mutating commands it owns, converting the global bare-function preflight into a scoped object form and adding tests and changelog entries to ensure and document the new behavior. Sequence diagram for scoped pm-github preflight overridesequenceDiagram
actor User
participant pm_core
participant pm_github_extension
participant Console
pm_github_extension->>pm_core: api.registerPreflight(commands, run)
User->>pm_core: runCommand(github sync)
pm_core->>pm_github_extension: run(ctx) [command in commands]
pm_github_extension->>pm_github_extension: isMutatingGithubCommand(ctx.command, ctx.options)
alt [isMutatingGithubCommand && no token]
pm_github_extension->>pm_github_extension: resolveGitHubToken()
pm_github_extension->>Console: console.error()
end
pm_core->>User: execute github sync handler (authoritative validation)
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Greptile SummaryThe PR scopes pm-github’s preflight warning to the six mutating command paths it owns, preventing unrelated extensions’ preflight overrides from colliding.
Confidence Score: 5/5The PR appears safe to merge with no concrete blocking or non-blocking defects identified. The scoped command list matches every path recognized by the existing mutation predicate, preserves the authoritative handler-level credential checks, and is pinned by the activation-harness test.
|
| Filename | Overview |
|---|---|
| index.ts | Scopes the existing non-blocking credential preflight to all six command paths recognized by the mutation predicate. |
| test/smoke.test.ts | Verifies through the activation harness that the preflight is registered as a scoped object with the exact intended paths. |
| CHANGELOG.md | Adds an Unreleased fix entry linked to the completed PM issue. |
| .agents/pm/issues/pm-github-yhhz.toon | Records the completed issue, affected files, and verification metadata. |
| .agents/pm/history/pm-github-yhhz.jsonl | Adds the corresponding append-only lifecycle history for the PM issue. |
Reviews (1): Last reviewed commit: "Scope preflight override to owned comman..." | Re-trigger Greptile
* Bind the preflight scope to pm-github's declared command set PR #36 scoped registerPreflight to a fixed six-entry commands array, but nothing binds that array to isMutatingGithubCommand or to the commands the package declares: if a command is added or reclassified as mutating on one side only, the override silently stops running for it (the runtime matches by exact normalized path) and it executes with no early credential warning. Extend the scoping smoke test into a drift guard: every scoped path must be one isMutatingGithubCommand treats as mutating — the apply-gated github export and github project sync are checked under their apply configuration rather than skipped — and every declared-but-omitted path (github validate, github project list, github project fields) must be read-only, proving the omission is justified rather than an accidental gap. Manifest-vs-scope audit: every scoped path is a declared command; the three omitted commands are read-only diagnostics that were never gated under the old global registration either. No gate lost; the legacy gh-issues import alias was already in scope. Verified: npm test 251/251; coverage 92.04 lines / 81.34 branches / 91.49 functions (thresholds 88/79/89); release:check exit 0; npx pm health --strict-exit ok: true. * Derive the preflight drift guard from real activation instead of a hand-maintained list Greptile (P2) and CodeRabbit (Major) independently raised the same objection to the guard added in the previous commit, and both were right. The test compared the override scope against DECLARED_READ_ONLY_COMMANDS, a second hand-maintained literal, and only checked that each CURRENT scope entry was mutating. So declaring a new mutating command while omitting it from both the scope and that literal left every assertion green - the guard could not detect the drift it was written for, which is worse than no guard because it reads as coverage. This matters more than a typical test-quality note. The whole point of the change is to NARROW a preflight scope, and narrowing is precisely the operation that can drop a command's credential gate silently: the runtime matches by exact normalized path, swallows preflight throws, and the authoritative handler gate only fires once the command has already run and failed. The test now derives the declared set from the real activation registrations - registerCommand, registerImporter and registerExporter - asserts the dispatch handler paths equal that derived set, partitions it with the same isMutatingGithubCommand predicate production uses rather than a second copy of the knowledge, and asserts the mutating and read-only classes reconstruct the declared set EXACTLY. That last assertion is the one that closes the finding: without it the hand-maintained list has merely moved. Verified non-vacuous rather than assumed. A scratch mutating command 'github scratch drift' was declared through registerCommand and added to isMutatingGithubCommand without touching the override scope; the suite failed 1 of 251 with 'preflight override scope must equal the mutating class of the declared command set exactly' and the diff named the command. The scratch command has been removed; 251 of 251 green. --------- Co-authored-by: SteveBot <1153461+unbraind@users.noreply.github.com>
Problem
registerPreflightused the bare-function form:The SDK types this as
PreflightOverride | ScopedPreflightOverrideDefinitionand documents the scoped form as "a preflight handler invoked only for a declared command, or globally when unscoped." So the bare form registers a global override. Every pair of globally-scoped overrides genuinely contends, andpm healthreports:With all six fleet packages installed together that is 15 pairwise warnings and
ok: false. None of them actually contend — each only guards its own credentials for its own commands.Fix
Use the scoped object form, declaring the command paths pm-github owns:
Why full command paths, not top-level names
The runtime matches a command against the
commandsarray by exact normalized path (entry.commands.includes(baseContext.command)), not by prefix. A bare top-level name likegithubnever matches the real commandgithub sync, so it would silently disable the early warning while still resolving the collision. The array therefore lists the full mutating command paths pm-github'sisMutatingGithubCommandalready recognizes.The authoritative credential gate stays in the command handlers; this only narrows the override's scope so it no longer contends with other packages' overrides.
Verified before/after
pm healthreportedok: falsewith oneextension_preflight_override_collisionwarning.pm healthreportedok: truewith zero collision warnings, and the guarded command still runs.Also tested and rejected: adding
contributions.commandsto the manifest does not resolve the collision — only the scopedregisterPreflightform does.Checklist
npm run release:checkexits 0npm run changelog:checkpassesnpx pm health --strict-exitexits 0pm item
Summary by Sourcery
Scope the pm-github preflight override to its own mutating command paths to avoid collisions with other extensions.
Bug Fixes:
Enhancements:
Tests:
Summary by cubic
Scopes
pm-github’sregisterPreflightoverride to its own mutating command paths to eliminate global collisions. Previously the bare-function form registered a global override that madepm healthreportextension_preflight_override_collision; now a scoped object lists exact command paths, preserving the early warning without contending with other packages.contributions.commandsdoes not resolve collisions.Written for commit ef107a5. Summary will update on new commits.