Skip to content

Complete agent self-service remediation registry (extension adoption + duplicate-issue-codes gaps) - #306

Merged
unbraind merged 3 commits into
mainfrom
feat/complete-remediation-registry-diagnostic-gaps
Jun 19, 2026
Merged

unbraind merged 3 commits into
mainfrom
feat/complete-remediation-registry-diagnostic-gaps

Conversation

@unbraind

@unbraind unbraind commented Jun 19, 2026 •

Copy link
Copy Markdown
Owner

Summary

Two diagnostic warning codes were emitted without a matching entry in the shared remediation registry (src/core/diagnostics/remediation.ts), so agents gating on pm health --json / pm validate --fix-hints received a warning with no machine-executable fix command and had to hardcode the remediation. This PR closes both gaps.

extension_update_health_partial_coverage — pm-bdvm

Emitted by the extensions health check when unmanaged extensions are present (a system-wide adoption gap, not a per-extension triage result).

  • Added a registry entry → pm extension --adopt-all --project.
  • Wired the extensions check into pm health's checkRemediationSources, which is now total over HealthCheck["name"] (the now-dead sources === undefined guard is removed).
  • Per-extension findings keep their richer details.triage.remediation and resolve to nothing in the registry, so only the system-wide adoption gap surfaces a remediation_map.

validate_metadata_duplicate_issue_codes — pm-sdbo (GH-235)

  • Added a registry entry → pm update <id> --title "<distinct title>" with a summary covering the rename-or-close-as-duplicate fix (using the structured pm close <id> --duplicate-of <canonical-id>, per Gemini review).
  • pm validate --check-metadata --fix-hints now lists an executable command for duplicate-issue-code findings.

GH-244 (pm-28cf) — verified, intentionally left open

Verified GH-244 (empty provider/adapter auto-detect source classification) is already fully implemented via resolveProviderConfigSource + the pm health provider_source/vector_store_source surfacing, shipped in #254 (release 2026.6.16). pm-28cf carries the verification note but is left open so closing it does not mis-bucket the CHANGELOG (it would otherwise list an already-shipped fix under the next release); it should be closed in a non-release-bearing touch.

Testing

  • resolveRemediation assertions for both new codes (tests/integration/remediation-registry.spec.ts).
  • pm health --json remediation_map assertion on the unmanaged-extension path (tests/unit/commands/health-command.spec.ts).
  • attachValidateFixHints assertion for the duplicate-issue-codes code (tests/unit/commands/validate-command.spec.ts).
  • Coverage 100/100/100/100, static-quality + docs-skills gates green, typecheck clean.
  • Sandbox-verified both end-to-end paths (unmanaged extension → adopt-all command; two duplicate-coded issues → title fix hint).
  • CHANGELOG.md regenerated via pm-changelog; Unreleased section contains only pm-bdvm + pm-sdbo.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GGxk19qUjiKKK6JdWjnquB

Two diagnostic warning codes were emitted without a matching entry in the
shared remediation registry, so agents gating on `pm health --json` /
`pm validate --fix-hints` got a warning with no machine-executable fix and had
to hardcode the remediation:

- extension_update_health_partial_coverage (pm-bdvm): unmanaged extensions the
  update-health scan had to skip. Added a registry entry pointing at
  `pm extension --adopt-all --project`, and wired the extensions check into
  `pm health`'s checkRemediationSources (now total over HealthCheck["name"],
  dropping the now-dead undefined-source guard). Per-extension findings keep
  their richer details.triage.remediation and resolve to nothing in the
  registry, so only the system-wide adoption gap surfaces a remediation_map.

- validate_metadata_duplicate_issue_codes (pm-sdbo, GH-235): added a registry
  entry with `pm update <id> --title "<distinct title>"` plus a summary
  covering the rename-or-close-as-duplicate fix, so `pm validate --fix-hints`
  now lists an executable command for duplicate-issue-code findings.

Also verified and closed pm-28cf: GH-244 (empty provider/adapter auto-detect
source classification) is already fully implemented via
resolveProviderConfigSource + the pm health provider_source/vector_store_source
surfacing; no code change required.

Tests: registry resolveRemediation assertions for both new codes, a
health-command remediation_map assertion, and a validate attachValidateFixHints
assertion. 100/100/100/100 coverage, static + docs gates green. Sandbox-verified
both end-to-end paths. CHANGELOG.md regenerated via pm-changelog.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GGxk19qUjiKKK6JdWjnquB

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @unbraind, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@unbraind

Copy link
Copy Markdown
Owner Author

@codex review
/gemini review
@coderabbitai full review

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai

coderabbitai Bot commented Jun 19, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Two new entries are added to the remediation registry for extension_update_health_partial_coverage and validate_metadata_duplicate_issue_codes warning codes. runHealth is updated to use a complete (non-partial) remediation source record, removing a conditional skip. Integration and unit tests verify both new registry entries. Changelog and PM agent tracking records are updated to reflect completion.

Changes

Remediation Registry Additions and Wiring

Layer / File(s) Summary
Remediation registry entries and health.ts wiring
src/core/diagnostics/remediation.ts, src/cli/commands/health.ts
Adds extension_update_health_partial_coverage and validate_metadata_duplicate_issue_codes entries to the remediation registry. Changes checkRemediationSources in runHealth from a Partial to a full Record, and removes the conditional guard so buildRemediationMap is always called for every check.
Integration and unit tests
tests/integration/remediation-registry.spec.ts, tests/unit/commands/health-command.spec.ts, tests/unit/commands/validate-command.spec.ts
Adds resolveRemediation integration tests for both new warning codes. Extends health-command unit test to assert remediation_map contains the extension entry. Extends validate-command unit test to assert attachValidateFixHints emits the fix hint for validate_metadata_duplicate_issue_codes:2.
Changelog and PM agent tracking records
CHANGELOG.md, .agents/pm/chores/pm-sdbo.toon, .agents/pm/chores/pm-bdvm.toon, .agents/pm/issues/pm-28cf.toon, .agents/pm/history/pm-sdbo.jsonl, .agents/pm/history/pm-bdvm.jsonl, .agents/pm/history/pm-28cf.jsonl
Adds two Added and one Fixed entry to CHANGELOG.md. Creates the pm-sdbo chore record and closes pm-bdvm. Closes pm-28cf issue. Updates JSONL history files with lifecycle events for all three tracking items.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • unbraind/pm-cli#111: Introduced the shared remediation registry, remediation_map in pm health --json, and pm validate --fix-hints machinery that this PR directly extends with two new warning-code entries and corresponding tests.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main objective: completing the remediation registry for two warning codes (extension adoption and duplicate-issue-codes gaps).
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description clearly details the addition of two remediation registry entries for diagnostic warning codes and their implementation, directly corresponding to the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds remediation registry entries for the extension_update_health_partial_coverage and validate_metadata_duplicate_issue_codes warnings. It updates pm health to make checkRemediationSources total over all health checks, ensuring the extensions check is properly wired into the remediation map. Corresponding integration and unit tests have been added to verify the resolution and mapping of these warnings. Feedback suggests updating the remediation summary for duplicate issue codes to recommend the structured --duplicate-of option instead of the free-text --reason option when closing redundant items.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +272 to +277
{
code: "validate_metadata_duplicate_issue_codes",
command: 'pm update <id> --title "<distinct title>"',
summary:
"Two or more items share one logical issue code (GH-235); give each a distinct title so the derived code is unique, or close the redundant item with pm close <id> --reason \"duplicate of <other-id>\" (closed-as-duplicate items are excluded from the check).",
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since pm close supports a structured --duplicate-of option (introduced in GH-183/GH-160) for duplicate tracking and auto-populating closure fields, we should suggest using pm close <id> --duplicate-of <other-id> instead of the free-text --reason "duplicate of <other-id>" in the remediation summary.

Suggested change
{
code: "validate_metadata_duplicate_issue_codes",
command: 'pm update <id> --title "<distinct title>"',
summary:
"Two or more items share one logical issue code (GH-235); give each a distinct title so the derived code is unique, or close the redundant item with pm close <id> --reason \"duplicate of <other-id>\" (closed-as-duplicate items are excluded from the check).",
},
{
code: "validate_metadata_duplicate_issue_codes",
command: 'pm update <id> --title "<distinct title>"',
summary:
"Two or more items share one logical issue code (GH-235); give each a distinct title so the derived code is unique, or close the redundant item with pm close <id> --duplicate-of <other-id> (closed-as-duplicate items are excluded from the check).",
},

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== PR Info ==="
gh pr view 306 --repo unbraind/pm-cli --json title,body,files,additions,deletions,baseRefName,headRefName

echo ""
echo "=== PR Files Changed ==="
gh pr diff 306 --repo unbraind/pm-cli

Length of output: 35944



@unbraind: Here's my full review of PR #306.

Overall Assessment

The PR cleanly closes two genuine agent-UX gaps and the type tightening (Partial<Record<…>> → Record<…>) is a solid improvement — TypeScript exhaustiveness checking now guarantees no new health check can silently go unregistered. Tests are well-targeted and the internal PM chore bookkeeping is consistent. A few things worth a closer look:


src/core/diagnostics/remediation.ts

extension_update_health_partial_coverage — scope flag hardcoded

{
  code: "extension_update_health_partial_coverage",
  command: "pm extension --adopt-all --project",   // <── always --project
  summary:
    "…use --global for global-scope extensions…",  // <── mentioned in prose only
},

The remediation_map entry agents receive will always carry --project. If the unmanaged extensions are in the global scope, an agent that faithfully executes the command from remediation_map will silently succeed on the wrong scope. Options:

  • Omit the scope flag entirely and let the command default (if that's safe): pm extension --adopt-all
  • Use a placeholder: pm extension --adopt-all <--project|--global>
  • Or, if the warning code already encodes the scope (e.g. …:skipped_unmanaged_global:<n>), that token could drive buildRemediationMap to emit two entries — one per scope.

validate_metadata_duplicate_issue_codes — template command

command: 'pm update <id> --title "<distinct title>"',

The angle-bracket placeholders mean this isn't directly shell-executable. That's a reasonable trade-off (other registries use templates too), but worth ensuring downstream consumers handle <…> markers gracefully rather than passing them literally to the CLI.


src/cli/commands/health.ts

The removal of the sources === undefined guard is correct — the type is now total, so the check was dead code. The logic is clean.

Missing negative assertion in the unit test

health-command.spec.ts asserts remediation_map contains extension_update_health_partial_coverage but doesn't assert that per-extension triage codes (e.g. load-failure codes) are absent. The comment notes this is intentional, but a negative assertion would cement the contract:

expect(
  (extensionCheck?.details as { remediation_map?: Record<string, string> }).remediation_map,
).toEqual({
  extension_update_health_partial_coverage: "pm extension --adopt-all --project",
  // Intentionally no per-extension triage codes (load_failure, etc.)
});

toEqual with an exact object already covers this — the test is fine as-is if buildRemediationMap only includes registered codes. Just a minor clarity note.


CHANGELOG.md

GH-244 appears in the ### Fixed section, but no new code was changed — the fix shipped in #254 and this PR only verified and closed the tracking item. A ### Maintenance / ### Chores bucket (if the changelog format supports one) would be more accurate; otherwise a parenthetical (verified already shipped in #254) avoids misleading readers about what changed in this release.


Summary

Area Severity Note
--project scope hardcoded in remediation command Medium Agents on global-scope extensions will run the wrong command
Template <id> placeholder in validate_metadata_duplicate_issue_codes Low Ensure consumers handle gracefully
No negative assertion for per-extension codes in unit test Nitpick toEqual already covers it implicitly
CHANGELOG Fixed vs Maintenance for GH-244 Nitpick Cosmetic accuracy

The scope issue in the extension remediation command is the only substantive concern. Everything else is well-executed.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds remediation registry entries for the extension_update_health_partial_coverage and validate_metadata_duplicate_issue_codes warnings, mapping them to executable fix commands. To support this, the checkRemediationSources map in src/cli/commands/health.ts was made total over all health checks, and corresponding unit and integration tests were added to verify the new remediation mapping behavior. I have no additional feedback to provide as the implementation is clean and well-tested.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

…e-codes remediation

Gemini review: pm close supports a structured --duplicate-of <id> flag
(GH-183/GH-160) that auto-fills duplicate closure metadata, so the
validate_metadata_duplicate_issue_codes remediation summary now points at
'pm close <id> --duplicate-of <canonical-id>' instead of the free-text
--reason "duplicate of <id>". The primary fix command (rename via --title)
is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GGxk19qUjiKKK6JdWjnquB
@unbraind

Copy link
Copy Markdown
Owner Author

Addressed Gemini's review in ea5f363: the validate_metadata_duplicate_issue_codes remediation summary now suggests the structured pm close <id> --duplicate-of <canonical-id> (auto-fills duplicate closure metadata) instead of free-text --reason. Re-requesting review.

@codex review
/gemini review
@coderabbitai full review

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai

coderabbitai Bot commented Jun 19, 2026 •

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Latest PR Diff ==="
gh pr diff 306 --repo unbraind/pm-cli

echo ""
echo "=== Commit ea5f3636 ==="
gh api repos/unbraind/pm-cli/commits/ea5f3636 --jq '.files[] | "FILE: \(.filename)\n\(.patch)\n"' 2>/dev/null || echo "Could not fetch commit details"

Length of output: 33054



@unbraind: Thanks for the update. Reviewed ea5f363 and the full diff. Here's the assessment:


ea5f363 — ✅ Good fix

The switch from free-text --reason "duplicate of <other-id>" to the structured --duplicate-of <canonical-id> flag is the right call. It's machine-parseable, auto-fills duplicate closure metadata, and is consistent with the CLI's own vocabulary. The summary now reads cleanly:

give each a distinct title so the derived code is unique, or close the redundant item with pm close <id> --duplicate-of <canonical-id> (closed-as-duplicate items are excluded from the check).


Remaining items from the prior review

Item Status
--project scope hardcoded in extension remediation command ✅ Mitigated — the summary now explicitly calls out --global for global-scope extensions. Since remediation_map commands are advisory starting points (agents read both command and summary), the prose guidance is sufficient.
Template <id> placeholder ✅ Acknowledged — design trade-off, consumers are expected to substitute. No change needed.
CHANGELOG GH-244 in ### Fixed Still open (nitpick) — the fix shipped in #254, not this PR. A ### Maintenance section or a parenthetical (verified already shipped in #254) would be more accurate, but this is cosmetic and not a blocker.
Negative assertion for per-extension triage codes in unit test ✅ — toEqual with the exact object already enforces absence; fine as-is.

Overall

The two substantive issues (extension scope ambiguity, duplicate-code remediation quality) are both addressed. The PR is in good shape. The only remaining note is the CHANGELOG cosmetic — happy to defer that if it's out of scope for this PR.

✅ Action performed

Full review finished.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds remediation registry entries for the extension_update_health_partial_coverage and validate_metadata_duplicate_issue_codes warnings. It updates src/cli/commands/health.ts to include the extensions check in checkRemediationSources and ensures the mapping is total over all health checks. Corresponding integration and unit tests have been added to verify the resolution of these warnings to their respective executable commands. Additionally, several tracking items have been closed and the changelog has been updated. There are no review comments to address, and I have no further feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

#254)

CodeRabbit + prior triage flagged that closing pm-28cf in this release-bearing
PR mis-buckets the CHANGELOG: GH-244's fix shipped in #254 (release 2026.6.16
via pm-gnu2), so listing it under the next release's Fixed is inaccurate.
Reopened pm-28cf with the verification note retained; it should be closed only
in a non-release-bearing touch. Regenerated CHANGELOG.md — the Unreleased
section now contains only this PR's two real additions (pm-bdvm, pm-sdbo), and
GH-244 remains correctly attributed to 2026.6.16.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GGxk19qUjiKKK6JdWjnquB
@unbraind

Copy link
Copy Markdown
Owner Author

Addressed CodeRabbit's CHANGELOG nitpick in 57b3964: GH-244's fix shipped in #254 (release 2026.6.16 via pm-gnu2), so closing pm-28cf in this release-bearing PR was mis-bucketing it under the next release's ### Fixed. Reopened pm-28cf (verification note retained — it remains a verified-shipped item to be closed in a non-release-bearing touch), and regenerated the CHANGELOG. The Unreleased section now contains only this PR's two real additions (pm-bdvm, pm-sdbo); GH-244 stays correctly attributed to 2026.6.16.

@coderabbitai full review
/gemini review

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Latest PR Diff (full) ==="
gh pr diff 306 --repo unbraind/pm-cli

echo ""
echo "=== Commit 57b39642 ==="
gh api repos/unbraind/pm-cli/commits/57b39642 --jq '.files[] | "FILE: \(.filename)\nPATCH:\n\(.patch)\n---"' 2>/dev/null || echo "Could not fetch commit details"

echo ""
echo "=== PR Status ==="
gh pr view 306 --repo unbraind/pm-cli --json title,state,commits,reviewDecision

Length of output: 45091



@unbraind: Reviewed 57b3964. The fix is exactly right.

57b3964 — ✅ Correct

One very minor observation (no action needed): pm-28cf.toon still carries a resolution field while status: open. The second note clarifies the deferral rationale clearly, so this is not misleading — just a documentation artifact from the intermediate close-then-reopen sequence. Fine as-is.


Final summary — all prior review items resolved

Item Status
--project scope hardcoded in extension remediation ✅ Mitigated via summary prose
Template <id> placeholder in duplicate-codes remediation ✅ Acknowledged design trade-off; --duplicate-of structured form added in ea5f363
No negative assertion for per-extension codes ✅ toEqual with exact object covers it
CHANGELOG GH-244 mis-bucketed under next release ✅ Resolved in 57b3964

The PR is clean. Happy to approve.

[approve]

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds remediation registry entries for the extension_update_health_partial_coverage and validate_metadata_duplicate_issue_codes warnings. It updates src/cli/commands/health.ts to make checkRemediationSources total over all health checks, registers the new commands in src/core/diagnostics/remediation.ts, and adds corresponding integration and unit tests. There are no review comments to evaluate, and I have no additional feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@unbraind
unbraind merged commit c7697a2 into main Jun 19, 2026
15 checks passed
@unbraind
unbraind deleted the feat/complete-remediation-registry-diagnostic-gaps branch June 19, 2026 21:31
unbraind added a commit that referenced this pull request Jun 23, 2026
…ase touch), fix pm-pfxi return-shape note

- Reopen pm-28cf: closing a verified-already-shipped tracker in a release-bearing
  PR mis-buckets pm-changelog (CodeRabbit + prior #306 triage both flagged it);
  close it in a dedicated non-release touch instead. Regenerate CHANGELOG.
- pm-pfxi: drop the non-existent `ok` field from the documented return shape so
  the task record matches the shipped { used, declared, missing, unused, findings }.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9qGjDPgdp6iNZ8HbKB6MQ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant