Skip to content

[Server] Untangle origin tracking from Registry#302

Open
chr-hertel wants to merge 1 commit into
mainfrom
refactor/untangle-registry-origin
Open

[Server] Untangle origin tracking from Registry#302
chr-hertel wants to merge 1 commit into
mainfrom
refactor/untangle-registry-origin

Conversation

@chr-hertel
Copy link
Copy Markdown
Member

Summary

  • Drops isManual from ElementReference (and the four subclasses); origin is no longer a property of the element.
  • Strips clear() / getDiscoveryState() / setDiscoveryState() from RegistryInterface; the Registry is now a flat last-write-wins map.
  • Adds idempotent unregisterTool/Resource/ResourceTemplate/Prompt(string) to RegistryInterface.
  • Rewrites DiscoveryLoader with a private owned-set diff so re-running load() only removes elements this loader itself contributed — preserves runtime registrations between discovery passes.
  • Introduces ChainLoader for explicit composition; Builder::build() composes loaders internally so the user-facing API is unchanged.
  • Manual-over-discovered precedence is preserved via loader ordering ([user, discovery, manual] — last-write-wins).

Supersedes #251: the runtime-registration regression that PR was fixing dissolves by construction, without adding a second origin flag (isDiscovered).

Test plan

  • make ci — phpstan clean, php-cs-fixer clean, 652 unit tests / 2146 assertions pass.
  • make inspector-tests — 87 tests pass (7 environmental skips, same as main).
  • New DiscoveryLoaderTest::testLoadDoesNotUnregisterRuntimeAdditions locks in the regression that [Server] fix: clear() wiping dynamically registered tools by tracking discovered state on references #251 was after.
  • combined-registration example still works end-to-end; the config://priority resource correctly resolves to the manual override (3 inspector snapshots updated to reflect this — they were previously showing the discovered version winning, which was a latent bug).

Breaking changes

  • ElementReference->isManual property removed.
  • RegistryInterface::register*() signatures lose the bool $isManual = false parameter.
  • RegistryInterface::clear(), getDiscoveryState(), setDiscoveryState() removed (only correct caller was DiscoveryLoader, which no longer needs them).

Pre-1.0, internal area — no userland impact known beyond what's documented above.

@chr-hertel chr-hertel force-pushed the refactor/untangle-registry-origin branch 6 times, most recently from 1864939 to 483922c Compare May 11, 2026 20:11
@chr-hertel
Copy link
Copy Markdown
Member Author

@soyuka that could be an alternative approach to #251, removing the leaky isManual and isolating it in that DiscoveryLoader

@chr-hertel chr-hertel force-pushed the refactor/untangle-registry-origin branch 5 times, most recently from ab11794 to ea5c5ec Compare May 11, 2026 21:18
@chr-hertel chr-hertel added the Server Issues & PRs related to the Server component label May 11, 2026
@chr-hertel chr-hertel force-pushed the refactor/untangle-registry-origin branch from ea5c5ec to 2c2456f Compare May 11, 2026 22:13
@soyuka
Copy link
Copy Markdown
Contributor

soyuka commented May 12, 2026

indeed, its a bit more complex then just a boolean though but I like the approach let me review.

soyuka
soyuka previously approved these changes May 12, 2026
Copy link
Copy Markdown
Contributor

@soyuka soyuka left a comment

Choose a reason for hiding this comment

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

Indeed this can replace my monkey patch its cleaner :)

*/
final class DiscoveryLoader implements LoaderInterface
{
private DiscoveryState $owned;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
private DiscoveryState $owned;
private DiscoveryState $owned = new DiscoveryState();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

won't work, see https://3v4l.org/i43rH

private array $namePatterns = DiscovererInterface::DEFAULT_NAME_PATERNS,
private LoggerInterface $logger = new NullLogger(),
) {
$this->owned = new DiscoveryState();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
$this->owned = new DiscoveryState();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

we could shift it to a constructor argument, but if we only do it for the way of how to instantiate the state, i'd rather keep it like this

Comment thread src/Server/Builder.php Outdated
foreach ($loaders as $loader) {
$loader->load($registry);
}
$loader = 1 === \count($loaders) ? $loaders[0] : new ChainLoader($loaders);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
$loader = 1 === \count($loaders) ? $loaders[0] : new ChainLoader($loaders);
$loader = new ChainLoader($loaders);

is probably fine

Drop the isManual flag from ElementReference and the discovery-state methods
from RegistryInterface. The Registry becomes a flat last-write-wins map;
DiscoveryLoader owns its own owned-set bookkeeping so re-running discovery
only removes elements it itself contributed. Adds ChainLoader for explicit
composition. Manual-over-discovered precedence is preserved via loader
ordering, not a flag on the reference.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@chr-hertel chr-hertel force-pushed the refactor/untangle-registry-origin branch from c2767d9 to 9abd95f Compare May 15, 2026 06:24
@chr-hertel chr-hertel added this to the 0.6.0 milestone May 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Server Issues & PRs related to the Server component

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants