Skip to content

SDK extension inventories, scoped activation, and stable agent context - #884

Merged
unbraind merged 4 commits into
mainfrom
feat/sdk-extension-context-runtime
Aug 3, 2026
Merged

SDK extension inventories, scoped activation, and stable agent context#884
unbraind merged 4 commits into
mainfrom
feat/sdk-extension-context-runtime

Conversation

@unbraind

@unbraind unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Summary

This broad SDK/CLI context-management tranche makes extension contributions statically discoverable and durable, honors declared activation scopes across every capability, stabilizes metadata caches across extension modes, adds token-bounded extension health to pm context, and turns failed declared extension commands into accurate actionable recovery. It also refreshes newly vulnerable transitive dependencies and the current compatible tsx patch.

  • Persist a typed schema-versioned contribution inventory from real install-time activation, with static manifest discovery and public SDK authoring contracts.
  • Make explicit activation.commands authoritative while preserving conservative compatibility for legacy packages and eager global contributions.
  • Retain up to four fingerprint-keyed metadata/body/collection cache variants so normal and --no-extensions reads stop evicting one another.
  • Add bounded extension_health context with --no-extension-health; empty installs add zero bytes and the large-workspace baseline remains exactly 1,231 estimated tokens.
  • Correlate unknown commands with declared contributions and activation failures before generic typo guidance, with aligned JSON/human recovery.
  • Require patched brace-expansion and PostCSS floors; refresh the lockfile and tsx 4.23.5.

PM lineage

Verification

  • 428 test files / 6,791 tests pass.
  • Coverage is exactly 100% statements, branches, functions, and lines.
  • ESLint has zero warnings; jscpd finds zero clones; docstring/export/member coverage gates are 100%.
  • Static SDK surface, package boundary/parity, token budget, context calibration, CLI transport, and entrypoint cost gates pass.
  • Secrets scan passes and pnpm audit reports no known vulnerabilities. GitHub Dependabot, code-scanning, and secret-scanning APIs reported zero open alerts before publication.
  • Packed npm/npx and Bun/bunx consumers were initialized in unrelated temporary roots; create/context JSON flows passed. A scaffolded third-party extension persisted contributions, invoked its lazily activated command, and appeared in context health.
  • The packaged npx smoke and 88-command package-first dogfood suite pass.
  • Real 2,000+ item alternating reads restore cached variants: list 0.432s/0.346s, get 0.440s/0.348s, context 1.771s/1.355s, and next 0.751s/0.694s for extension/no-extension modes.
  • pm validate reports zero history drift. The graph has 10,781 edges with no active isolated or degree-one items; remaining graph findings are legacy informational history.
  • pm-changelog@2026.8.3 is current and generated CHANGELOG.md is unchanged because these items remain in progress until merge/release proof.

Compatibility notes

npm-package-arg 14 is intentionally not adopted because its Node engine excludes the supported Node 22.18 floor. TypeScript 7 is intentionally deferred because the current typescript-eslint peer range is below 6.1. These are incompatible majors rather than unattended safe updates.

Summary by Sourcery

Stabilize extension-related runtime behavior by introducing a static contribution inventory, tightening activation scoping, preserving multiple metadata cache variants per context, and exposing installed extension health in pm context, alongside improved CLI recovery for failed extension commands and refreshed dependency floors.

New Features:

  • Persist a schema-versioned extension contribution inventory at install time and expose it through SDK authoring and managed extension state.
  • Add a token-bounded installed extension health summary to pm context, with CLI flags and tool contracts to opt out.
  • Support static extension-manifest contributions for discovery without importing extension modules and surface them in install results and docs.
  • Enhance CLI unknown-command handling to correlate failures with declared extension commands and return actionable recovery guidance in text and JSON.

Enhancements:

  • Bound item metadata caches to up to four context fingerprints so extension and no-extension modes retain separate cache variants and degrade gracefully when enumeration fails.
  • Refine extension activation decisions to honor explicit activation.commands for all capabilities while still activating global contribution surfaces when required.
  • Refactor extension discovery and loader logic to normalize manifests, managed state, and contribution inventories into shared contracts and helper modules.
  • Extend context markdown and release readiness checks to include extension health projections and section coverage.
  • Adjust governance-audit extension manifest and activation behavior to align with new activation and contribution rules.

Build:

  • Raise brace-expansion and postcss dependency floors, add a minimum-age exclusion for tsx 4.23.5, and bump the tsx dev dependency version in package.json.

Documentation:

  • Update extension authoring documentation and manifest schema to describe the contribution inventory contract, authoritative activation.commands semantics, and install-time persistence.
  • Refresh fixtures and public SDK surface documentation to reflect new context flags, parameters, and extension health fields.

Tests:

  • Add unit and integration coverage for contribution inventory normalization and persistence, context extension health behavior, bounded cache identity handling, and extension command activation recovery flows.
  • Update existing extension startup, CLI error, recovery, and release-readiness tests to validate new activation decisions, diagnostics, and context sections.

Summary by cubic

Persist extension contributions and enforce command-scoped activation to load only what’s needed. Adds extension health to pm context, hardens and stabilizes cache variants across modes, improves failed command recovery, and updates vulnerable deps.

  • New Features

    • Persisted versioned contribution inventory and public SDK helpers (createExtensionContributionInventory, normalizeExtensionContributionInventory).
    • Scoped activation honors declared activation.commands across all capabilities; uses static contributions for matching.
    • Metadata cache keeps up to four fingerprinted variants and safely prunes them; context variants are memoized so extension/--no-extensions modes don’t evict each other.
    • pm context includes token-bounded extension_health; opt out with --no-extension-health (SDK: noExtensionHealth).
    • Recovery for unresolved extension commands leads with declared-command correlation and repair suggestions; publishes extension_command_activation_failed and JSON extension_command_failure.
    • Manifest schema adds contributions; publishes CLI/SDK contracts for --no-extension-health and the new error code.
  • Dependencies

    • Patched transitive vulnerabilities: brace-expansion ≥ 5.0.9, postcss ≥ 8.5.23; bumped tsx to ^4.23.5.
    • Intentionally defer incompatible majors (npm-package-arg@14, TypeScript 7).

Written for commit 57515f5. Summary will update on new commits.

Review in cubic

Deliver a cohesive SDK/CLI context-management tranche across pm-021kdp, pm-j0w7j9, pm-77okxr, pm-h85e, pm-4uplae, and pm-2cv2o1. Persist typed contribution inventories, honor command-scoped activation, retain bounded cache variants, expose token-bounded extension health, improve failed extension-command recovery, and refresh vulnerable transitive dependencies.

Verification includes 6,791 tests at 100/100/100/100 coverage, strict lint/docstring/duplication gates, packed npm and Bun consumers, scaffolded extension activation, real-scale alternating-cache measurements, secrets scanning, and zero pnpm audit findings.
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@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

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

@greptileai please perform a full review of this broad SDK/CLI context-management tranche.

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

@unbraind I will perform a full review of PR #884.

✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 59 minutes.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added extension contribution inventories for more reliable discovery and activation.
    • Added extension health summaries to context results, with an option to hide them.
    • Improved extension command recovery with clearer diagnostics and actionable guidance.
    • Added context-aware cache reuse and bounded cache retention.
  • Bug Fixes

    • Improved activation behavior for commands, hooks, renderers, search, and other extension capabilities.
    • Preserved compatibility for legacy extensions and installations.
  • Documentation

    • Updated extension manifest guidance and schema documentation.

Walkthrough

This change adds schema-versioned extension contribution inventories, static activation discovery, persisted runtime metadata, command-specific recovery diagnostics, extension health reporting, context-aware cache variants, dependency updates, and project execution records.

Changes

Extension contribution inventories and activation

Layer / File(s) Summary
Inventory contracts and manifest parsing
src/core/extensions/*, docs/schemas/extension-manifest.schema.json, src/sdk/authoring.ts, sdk/public-surface.json, docs/EXTENSIONS.md
Adds normalized contribution inventories to extension contracts, manifests, schemas, loaders, authoring exports, and SDK surface records.
Runtime inventory persistence
src/sdk/extension.ts, src/sdk/extension/managed-state.ts, src/sdk/extension/runtime-summary.ts
Derives inventories from activation results and persists them during installation and adoption.
Static activation and command recovery
src/cli/main.ts, src/cli/extension-recovery.ts, src/cli/commander-usage.ts, tests/cli/*, tests/integration/extension-*
Uses declared contribution paths for activation decisions and reports scoped text and JSON recovery details for failed declared commands.

Context health and cache behavior

Layer / File(s) Summary
Extension health projection and CLI contracts
src/sdk/query/context.ts, src/cli/register-list-query.ts, src/sdk/cli-contracts/*, tests/unit/commands/context-extension-health.spec.ts
Adds bounded extension health output, Markdown rendering, and the --no-extension-health option.
Context-fingerprinted cache variants
src/core/store/item-metadata-cache.ts, tests/unit/core/item/item-metadata-cache.spec.ts
Adds context-specific cache selection, diagnostics, bounded retention, and best-effort publication behavior.

Project metadata and dependency maintenance

Layer / File(s) Summary
Dependency and extension manifest updates
package.json, pnpm-workspace.yaml, packages/pm-governance-audit/extensions/governance-audit/manifest.json, .agents/pm/extensions/.managed-extensions.json
Updates tool and dependency versions, release-age exclusions, and managed extension metadata.
Feature and issue execution records
.agents/pm/features/*, .agents/pm/issues/*, .agents/pm/history/*
Records ownership, implementation evidence, verification data, affected files, compatibility notes, and passing test runs.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Manifest as Extension manifest
  participant Loader as Extension loader
  participant Probe as Runtime probe
  participant State as Managed state
  participant CLI as CLI activation
  participant Context as Context command
  Manifest->>Loader: provide contribution inventory
  Loader->>Probe: expose normalized extension metadata
  Probe->>State: persist activation-derived inventory
  CLI->>Loader: inspect static contribution paths
  Loader-->>CLI: return activation decision
  Context->>Loader: discover installed extensions
  Loader-->>Context: return diagnostics and health metadata
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title clearly summarizes the main SDK and CLI extension changes, including inventories, activation scoping, and agent context.
Description check ✅ Passed The description directly covers the extension inventories, activation, caching, context health, recovery, dependencies, and verification changes.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • 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.

@sourcery-ai

sourcery-ai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements static extension contribution inventories and scoped activation semantics, adds token-bounded extension health to pm context, stabilizes item metadata caches across multiple extension/no-extension contexts, and enhances CLI recovery for failed extension commands, alongside small dependency and docs updates.

Sequence diagram for pm context extension health projection

sequenceDiagram
  actor User
  participant CliContextCommand as pm_context_cli
  participant SdkContext as runContext
  participant HealthProjection as resolveContextExtensionHealthProjection
  participant ExtensionDiscovery as discoverExtensions

  User->>CliContextCommand: pm context --no-extension-health?
  CliContextCommand->>SdkContext: runContext(ContextOptions)
  SdkContext->>HealthProjection: resolveContextExtensionHealthProjection(options.noExtensionHealth, pmRoot, settings)
  HealthProjection->>ExtensionDiscovery: discoverExtensions({ pmRoot, settings, cwd, noExtensions: false })
  ExtensionDiscovery-->>HealthProjection: discovery.discovered
  HealthProjection-->>SdkContext: { extension_health? }
  SdkContext->>SdkContext: Object.assign(result, extension_health)
  SdkContext-->>CliContextCommand: ContextResult
  CliContextCommand-->>User: context JSON/markdown with extension_health
Loading

File-Level Changes

Change Details Files
Bounded, fingerprinted item metadata cache variants to keep extension and non-extension reads from evicting each other.
  • Add per-context cache filenames and helper to derive a fingerprinted cache path.
  • Load cache, body, and collections envelopes with an optional context fingerprint and emit diagnostics when active and requested contexts diverge.
  • Persist per-context cache variants, keep an in-memory memo, and prune older variants beyond a MAX_CACHE_CONTEXTS limit.
  • Extend listAllDocumentCandidatesCached options with cacheDiagnostics and exercise behavior with new unit tests, including best-effort publication when runtime enumeration fails.
src/core/store/item-metadata-cache.ts
tests/unit/core/item/item-metadata-cache.spec.ts
Make extension activation respect explicitly declared activation.commands while using static contribution inventories and conservative heuristics for legacy/global behavior.
  • Broaden extensionActivationCommands to derive commands from contribution surfaces when activation.commands is absent.
  • Introduce helpers to match static extension commands, detect global contributions, and resolve static activation decisions before falling back to capability heuristics.
  • Adjust extensionNeedsActivationForProbe to honor explicit activation commands as authoritative and treat hooks/renderers without matching commands as non-activating.
  • Update integration and unit tests for renderer/hook activation behavior and search-provider activation commands.
src/cli/main.ts
tests/integration/extension-startup.integration.spec.ts
tests/unit/cli/cli-main-errors.spec.ts
Persist and normalize a versioned, serializable extension contribution inventory at install time and expose it through SDK and loader contracts.
  • Define ExtensionContributionInventory type on core extension types and add optional contributions to manifests, effective extensions, candidates, and managed records.
  • Add normalization and creation helpers for inventories, using command-name normalization and validating renderer ownership and preflight counts.
  • Use normalized contributions when parsing manifests and managed state and attach manifest or managed contributions to EffectiveExtension summaries.
  • Capture runtime activation summaries into contribution inventories during extension install/adopt flows, persist them in managed state, and expose them via SDK authoring and extension APIs.
  • Refactor loader candidate construction into a dedicated helper that includes persisted contributions.
  • Update manifest schema docs and examples to document contributions and their role in static discovery.
src/core/extensions/extension-types.ts
src/core/extensions/contribution-inventory.ts
src/core/extensions/extension-candidate.ts
src/core/extensions/loader.ts
src/sdk/extension/shared.ts
src/sdk/extension.ts
src/sdk/extension/managed-state.ts
src/sdk/authoring.ts
docs/EXTENSIONS.md
tests/unit/extensions/contribution-inventory.spec.ts
tests/unit/extensions/extension-loader.spec.ts
Add static, token-bounded extension health to pm context output with CLI/SDK wiring and tests.
  • Extend context options, flag contracts, and tool parameter mappings with a noExtensionHealth toggle and register a corresponding CLI option.
  • Discover installed extensions without importing modules and compute an extension_health projection summarizing ok/degraded packages with truncation for large workspaces.
  • Attach extension_health to ContextResult, render a concise summary line in markdown, and ensure release-readiness/runtime tests cover the section.
  • Add an integration test ensuring extension health is derived statically, is omittable, and bounded to 20 package rows with truncation metadata.
src/sdk/query/context.ts
src/sdk/cli-contracts/flag-contracts.ts
src/sdk/cli-contracts/tool-option-contracts.ts
src/sdk/cli-contracts/tool-parameter-tables.ts
src/cli/register-list-query.ts
tests/unit/commands/context-extension-health.spec.ts
tests/integration/release-readiness-runtime.spec.ts
Improve CLI recovery and usage output for failed extension command activations, correlating unknown commands with declared contributions.
  • Extend ExtensionRecoveryFailure with declared command metadata and bounded recovery commands.
  • Update extension recovery helpers to normalize and compare attempted command paths against declared inventories and populate recovery_commands for matches.
  • Wire attempted command paths from the bootstrap probe into unknown-command and commander-usage error handlers so recovery can be scoped to the failing command.
  • Adjust commander usage rendering to prioritize a declared extension command failure (with repair suggestions) before generic unknown-command guidance, for both human and JSON output.
  • Add unit and integration tests for recovery matching behavior, JSON annotations, and ordering of messages.
src/cli/extension-recovery.ts
src/cli/commander-usage.ts
src/cli/main.ts
tests/unit/cli/recovery-context-usage.spec.ts
tests/integration/extension-command-recovery.integration.spec.ts
Refresh dependency overrides and test/manifest metadata for security and compatibility.
  • Tighten brace-expansion and postcss version floors in pnpm-workspace overrides and update tsx dev dependency.
  • Adjust governance-audit extension manifest to drop activation.commands now that contributions/activation semantics are revised.
  • Update fixtures and public SDK surface descriptors to include new context and extension fields.
  • Refresh pnpm lockfile and internal lineage/history artifacts for the new features.
pnpm-workspace.yaml
package.json
packages/pm-governance-audit/extensions/governance-audit/manifest.json
tests/fixtures/contracts/full.json
sdk/public-surface.json
pnpm-lock.yaml
.agents/pm/**/*

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@codspeed-hq

codspeed-hq Bot commented Aug 3, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 11 untouched benchmarks


Comparing feat/sdk-extension-context-runtime (57515f5) with main (d4b1c49)

Open in CodSpeed

@codecov

codecov Bot commented Aug 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Regenerate the full CLI/SDK/MCP contract snapshot, public error-code catalog, and SDK surface after hosted CI identified the missing noExtensionHealth and extension_command_activation_failed projections. Link the exact hosted gate and generated artifacts to pm-h85e and pm-4uplae.
@unbraind

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

Regarding #884 (comment): acknowledged. Gemini Code Assist has ceased review activity, so this notice provides no actionable code finding; the PR remains covered by the active hosted security, analysis, coverage, and requested review agents.

@unbraind

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

Regarding #884 (comment): acknowledged the CodeRabbit usage-limit notice. The exact head is now 79d056499; a new full review is requested below because the hosted contract follow-up changed generated SDK and MCP surfaces.

@unbraind

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

Regarding #884 (comment): the initial CodeRabbit run covered c0fd1d79; the updated head 79d056499 adds the missing generated contract/error-code/public-surface projections identified by CI. Please evaluate the complete new head rather than treating the earlier processing state as final.

@unbraind

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

Regarding #884 (comment): the Sourcery guide accurately captures the six behavior areas. The follow-up head additionally publishes extension_command_activation_failed in the generated error catalog and all noExtensionHealth CLI/SDK/MCP schemas; pnpm run contracts:check now reproduces the hosted static lane.

@unbraind

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

Regarding #884 (comment): the unchanged CodSpeed benchmark set is consistent with the PR. The cache regression is additionally verified on the real 2,000+ item tracker: restored alternating list variants are 0.432s/0.346s and no longer mutually trigger 5s corpus rebuilds.

@unbraind

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

Regarding #884 (comment): acknowledged and verified. Codecov reports every modified coverable line covered; the complete local suite independently passes 6,791 tests at exact 100% statements/branches/functions/lines.

@unbraind

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

Regarding Sourcery review 4847592077: the weekly diff-character limit prevented an actionable Sourcery review. This is recorded as a reviewer limitation, not a clean finding; CodeRabbit, Greptile, CodeQL, DeepScan, Semgrep, Trivy, CodeFactor, and the repository gates remain the evidence sources for this head.

@unbraind

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

@greptileai please perform a full exact-head review of 79d056499, including the hosted contract follow-up.

@coderabbitai full review

The new head fixes the first CI finding by regenerating the CLI/SDK/MCP contract snapshot, public error-code catalog, and SDK surface; pnpm run contracts:check and strict lint now pass locally.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

@unbraind I will perform a full review of PR #884 at exact head 79d056499. I will include the hosted contract follow-up and the regenerated CLI, SDK, MCP, error-catalog, and public SDK-surface outputs.

✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 44 minutes.

@coderabbitai coderabbitai 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.

Actionable comments posted: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/core/store/item-metadata-cache.ts (2)

392-429: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Fix the active === null short-circuit in loadCache.

The guard returns active before checking the fingerprinted variant when active === null. Compare with loadBodyCache (line 449) and loadCollectionsCache (line 475): both use active?.context_fingerprint !== contextFingerprint, which is true when active is null, so both correctly attempt the fingerprinted variant even when the primary cache is missing. loadCache does not do this. If the primary metadata cache file is absent (deleted, corrupted, or pruned) but the requested context's fingerprinted variant exists on disk, loadCache returns null and skips the variant entirely, forcing a full rebuild and never reporting the metadata_cache_context_changed diagnostic. Align loadCache with the other two loaders.

🐛 Proposed fix
   const cachePath = getCachePath(pmRoot);
   const active = await loadEnvelopeMemoized(cachePath, parse);
-  if (
-    !contextFingerprint ||
-    active === null ||
-    active.context_fingerprint === contextFingerprint
-  ) {
-    return active;
-  }
+  if (!contextFingerprint || active?.context_fingerprint === contextFingerprint) {
+    return active;
+  }
   const retained = await loadEnvelopeMemoized(
     getContextCachePath(cachePath, contextFingerprint),
     parse,
   );
   if (retained === null) {
     appendWarning(
       diagnostics,
-      `metadata_cache_context_changed:${active.context_fingerprint}->${contextFingerprint}`,
+      `metadata_cache_context_changed:${active?.context_fingerprint ?? "none"}->${contextFingerprint}`,
     );
   }
   return retained;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/store/item-metadata-cache.ts` around lines 392 - 429, Update the
guard in loadCache so a missing active envelope does not short-circuit loading
the context-specific variant. Align its condition with loadBodyCache and
loadCollectionsCache by using the optional active context_fingerprint
comparison, while preserving the existing return and
metadata_cache_context_changed diagnostic behavior.

431-481: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider parity for context-mismatch diagnostics.

loadCache records a metadata_cache_context_changed diagnostic when no matching fingerprinted variant exists. loadBodyCache and loadCollectionsCache have no diagnostics parameter and silently return null in the same scenario. Body/collections cache misses are just as impactful (they force a full re-read of item bodies/collections) but are invisible to callers inspecting cacheDiagnostics. Extend the same diagnostic reporting to these two loaders for consistency.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/store/item-metadata-cache.ts` around lines 431 - 481, Extend
loadBodyCache and loadCollectionsCache to accept the diagnostics sink used by
loadCache, and record a metadata_cache_context_changed diagnostic when a context
fingerprint is requested but no matching fingerprinted cache variant is found.
Update their callers to pass the diagnostics object while preserving existing
cache fallback and return behavior.
src/sdk/extension.ts (1)

2370-2404: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Preserve manifest contributions when runtime activation fails.

runtimeProbe.contribution_inventories[name] is a truthy object whenever the extension loads, even if activation fails and the activation summary records no registered surfaces. The if (contributionInventory) check therefore still replaces the manifest-declared contributions stored just before the runtime probe with an empty inventory, and the install result exposes the same empty contributions.

Only apply the runtime inventory when activation.activated is true; otherwise keep validated.manifest.contributions for both persisted state and the install result.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/sdk/extension.ts` around lines 2370 - 2404, Update the contribution
inventory handling in the install flow so runtimeProbe.contribution_inventories
is persisted and returned only when activation.activated is true. When
activation fails, retain validated.manifest.contributions in
persisted.managedState and the install result instead of replacing it with the
runtime inventory.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.agents/pm/features/pm-021kdp.toon:
- Around line 33-45: Link sdk/public-surface.json to pm-021kdp by registering it
through the PM CLI and regenerating the derived artifacts. Update
.agents/pm/features/pm-021kdp.toon lines 33-45 to include the file, and preserve
the generated append-only entry in .agents/pm/history/pm-021kdp.jsonl lines 5-5;
do not edit the history file directly.

In @.agents/pm/features/pm-h85e.toon:
- Around line 46-53: The PM item’s affected-file list is missing the
release-readiness integration test. Register
tests/integration/release-readiness-runtime.spec.ts with pm using the
appropriate CLI, then regenerate the derived artifacts; update
.agents/pm/features/pm-h85e.toon at lines 46-53 and preserve the CLI-generated
append-only entry in .agents/pm/history/pm-h85e.jsonl at line 9 without editing
history directly.

In `@src/cli/register-list-query.ts`:
- Around line 1098-1101: Update the CLI option normalization before runContext
so Commander’s extensionHealth: false result is translated to noExtensionHealth:
true, matching the existing noTags translation in normalizeContextOptions. Add
CLI-level coverage verifying --no-extension-health suppresses the extension
health summary.

In `@src/core/extensions/contribution-inventory.ts`:
- Around line 128-175: Update createExtensionContributionInventory to
canonicalize summary.renderer_ownership before assigning it, reusing
normalizeRendererOwnership so each renderer’s commands are deduplicated and
sorted consistently with normalizeExtensionContributionInventory. Preserve the
existing conditional omission when renderer_ownership is absent.

In `@src/core/store/item-metadata-cache.ts`:
- Around line 580-589: Update the variants filter in the cache-pruning logic to
exclude the primary cache file by comparing each entry name against the primary
filename, while retaining only fingerprinted files matching the existing stem
and extension criteria. Ensure the primary file cannot be counted toward
MAX_CACHE_CONTEXTS or selected for removal.
- Around line 571-576: Update the context-fingerprinted write path using
contextPath and envelopeMemo so it stores the just-written envelope in the memo
after writeFileAtomic, matching the primary cache write behavior, rather than
deleting the entry.
- Around line 590-599: Update the pruning logic in the variants Promise.all
within persistCache to handle fs.stat failures per variant. Treat a missing or
otherwise unavailable variant as already gone, exclude it from age sorting and
deletion, and ensure one rejected stat cannot propagate out of persistCache or
interrupt metadata/body/collections persistence.
- Around line 566-570: In persistCache, extract
path.dirname(path.dirname(cachePath)) into a single pmRoot value and reuse it in
the getCachePath, getBodyCachePath, and getCollectionsCachePath comparisons.
Keep the existing cache-path matching behavior unchanged.

In `@tests/integration/extension-command-recovery.integration.spec.ts`:
- Around line 29-45: Guard the built-artifact dependency in the integration test
before invoking spawnSync: validate that dist/cli.js exists and fail with a
clear build-related message if it is missing, then preserve the existing process
status and recovery-message assertions. Alternatively, switch this test to
execute src/cli.ts through tsx consistently with
extension-startup.integration.spec.ts.

In `@tests/unit/cli/cli-main-errors.spec.ts`:
- Around line 1433-1445: Extend the hasGlobalExtensionContributions tests around
the existing assertion to cover the renderer comparison branch: add one case
where renderer_overrides contains a format without a matching renderer_ownership
record and expect eager activation, plus another where every overridden format
is owned and expect no renderer contribution. Use the existing contribution
object shape and keep the hooks and empty-inventory assertions unchanged.

In `@tests/unit/core/item/item-metadata-cache.spec.ts`:
- Around line 679-684: In the retention-count assertion for retainedContexts,
replace the broad range checks with an exact expectation of four files. Keep the
existing metadata-cache filename filtering and test setup unchanged so the
assertion verifies the four-variant retention boundary and catches pruning
off-by-one errors.
- Around line 688-733: Add an analogous test beside “keeps cache publication
best-effort when retained-context enumeration fails” that spies on fs.stat and
throws for one retained variant path, then verifies
listAllDocumentCandidatesCached still completes successfully. Exercise the
retained-variant persistence path and restore the spy in cleanup, confirming the
stat failure is tolerated after the corresponding persistCache guard is added.

---

Outside diff comments:
In `@src/core/store/item-metadata-cache.ts`:
- Around line 392-429: Update the guard in loadCache so a missing active
envelope does not short-circuit loading the context-specific variant. Align its
condition with loadBodyCache and loadCollectionsCache by using the optional
active context_fingerprint comparison, while preserving the existing return and
metadata_cache_context_changed diagnostic behavior.
- Around line 431-481: Extend loadBodyCache and loadCollectionsCache to accept
the diagnostics sink used by loadCache, and record a
metadata_cache_context_changed diagnostic when a context fingerprint is
requested but no matching fingerprinted cache variant is found. Update their
callers to pass the diagnostics object while preserving existing cache fallback
and return behavior.

In `@src/sdk/extension.ts`:
- Around line 2370-2404: Update the contribution inventory handling in the
install flow so runtimeProbe.contribution_inventories is persisted and returned
only when activation.activated is true. When activation fails, retain
validated.manifest.contributions in persisted.managedState and the install
result instead of replacing it with the runtime inventory.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4ef1f79f-61d1-4909-85a7-318a6e80d341

📥 Commits

Reviewing files that changed from the base of the PR and between d4b1c49 and c0fd1d7.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (47)
  • .agents/pm/extensions/.managed-extensions.json
  • .agents/pm/features/pm-021kdp.toon
  • .agents/pm/features/pm-h85e.toon
  • .agents/pm/history/pm-021kdp.jsonl
  • .agents/pm/history/pm-2cv2o1.jsonl
  • .agents/pm/history/pm-4uplae.jsonl
  • .agents/pm/history/pm-77okxr.jsonl
  • .agents/pm/history/pm-h85e.jsonl
  • .agents/pm/history/pm-j0w7j9.jsonl
  • .agents/pm/issues/pm-2cv2o1.toon
  • .agents/pm/issues/pm-4uplae.toon
  • .agents/pm/issues/pm-77okxr.toon
  • .agents/pm/issues/pm-j0w7j9.toon
  • docs/EXTENSIONS.md
  • docs/schemas/extension-manifest.schema.json
  • package.json
  • packages/pm-governance-audit/extensions/governance-audit/manifest.json
  • pnpm-workspace.yaml
  • sdk/public-surface.json
  • src/cli/commander-usage.ts
  • src/cli/extension-recovery.ts
  • src/cli/main.ts
  • src/cli/register-list-query.ts
  • src/core/extensions/contribution-inventory.ts
  • src/core/extensions/extension-candidate.ts
  • src/core/extensions/extension-types.ts
  • src/core/extensions/loader.ts
  • src/core/store/item-metadata-cache.ts
  • src/sdk/authoring.ts
  • src/sdk/cli-contracts/flag-contracts.ts
  • src/sdk/cli-contracts/tool-option-contracts.ts
  • src/sdk/cli-contracts/tool-parameter-tables.ts
  • src/sdk/extension.ts
  • src/sdk/extension/managed-state.ts
  • src/sdk/extension/runtime-summary.ts
  • src/sdk/extension/shared.ts
  • src/sdk/query/context.ts
  • tests/fixtures/contracts/full.json
  • tests/integration/extension-command-recovery.integration.spec.ts
  • tests/integration/extension-startup.integration.spec.ts
  • tests/integration/release-readiness-runtime.spec.ts
  • tests/unit/cli/cli-main-errors.spec.ts
  • tests/unit/cli/recovery-context-usage.spec.ts
  • tests/unit/commands/context-extension-health.spec.ts
  • tests/unit/core/item/item-metadata-cache.spec.ts
  • tests/unit/extensions/contribution-inventory.spec.ts
  • tests/unit/extensions/extension-loader.spec.ts

Comment thread .agents/pm/features/pm-021kdp.toon Outdated
Comment thread .agents/pm/features/pm-h85e.toon Outdated
Comment thread src/cli/register-list-query.ts
Comment thread src/core/extensions/contribution-inventory.ts
Comment thread src/core/store/item-metadata-cache.ts
Comment thread src/core/store/item-metadata-cache.ts Outdated
Comment thread tests/integration/extension-command-recovery.integration.spec.ts
Comment thread tests/unit/cli/cli-main-errors.spec.ts
Comment thread tests/unit/core/item/item-metadata-cache.spec.ts Outdated
Comment thread tests/unit/core/item/item-metadata-cache.spec.ts
Map Commander negated extension-health options into the SDK contract, memoize context variants after publication, and make bounded cache pruning resilient to concurrent removals. Add exact retention, filesystem-race, real CLI option, and built-entrypoint regression coverage while recording review evidence on the canonical pm items.
@unbraind

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

CodeRabbit exact-head follow-up: all 12 inline threads were individually acknowledged and reacted to; the nine actionable findings are fixed in c361624e2, the three already-resolved findings were reverified, and every thread is resolved. The full local suite now passes 6,792 tests at exact 100% statements/branches/functions/lines; lint, zero-clone analysis, 100% docstring quality, static quality, and contract checks pass. The summary warning that cites 55.56% docstring coverage does not use this repository’s enforced TypeScript-aware gate; the repository gate reports the required 100% source/export/member docstring coverage. Please assess the new exact head.

@unbraind

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review\n\n@greptileai please perform a full exact-head review of c361624e2, including all review-fix changes.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

@unbraind I will perform a full review of PR #884 at exact head c361624e2. I will include all review-fix changes.

✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 25 minutes.

@unbraind

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

Regarding CodeRabbit review invocation 72a1b8db-33f1-43be-a18c-c7457cbbd3a8: acknowledged. The exact-head rerun was prevented by the included-review limit, so it is recorded as a reviewer limitation rather than a clean review. All earlier actionable CodeRabbit threads were fixed, individually answered/reacted to, and resolved; the new exact head is independently green across every hosted required check and the complete local suite.

Attach the green hosted matrix, 6,792-test 100% coverage result, resolved CodeRabbit findings, and explicit reviewer quota limitations to each active canonical item.
@unbraind

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@unbraind

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

@greptileai please perform a full exact-head review of 57515f545; this final follow-up changes only append-only PM evidence after the reviewed code head.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 22 minutes.

@unbraind

unbraind commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

Regarding the final CodeRabbit invocation on 57515f545: acknowledged. The PM-only evidence commit was again rate-limited; it contains no source behavior changes. The last substantive code head has all findings fixed and resolved, and the final head has a fully green hosted matrix with zero unresolved threads.

@unbraind
unbraind merged commit 657f8fa into main Aug 3, 2026
32 checks passed
@unbraind
unbraind deleted the feat/sdk-extension-context-runtime branch August 3, 2026 19:36
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