feat(core): qualify resource URIs by toolkit and version [TOO-1933] - #919
Open
EricGustin wants to merge 1 commit into
Open
Conversation
10 tasks
Codecov Report❌ Patch coverage is
🚀 New features to boost your workflow:
|
EricGustin
force-pushed
the
ericgustin/too-1932-resource-registry
branch
from
August 26, 2026 06:56
28189ab to
155d9b0
Compare
EricGustin
force-pushed
the
ericgustin/too-1933-qualify-resource-uris
branch
from
August 26, 2026 06:56
0691947 to
576a579
Compare
EricGustin
force-pushed
the
ericgustin/too-1932-resource-registry
branch
from
August 26, 2026 18:20
155d9b0 to
32e510b
Compare
EricGustin
force-pushed
the
ericgustin/too-1933-qualify-resource-uris
branch
from
August 26, 2026 18:20
576a579 to
0827a8e
Compare
EricGustin
force-pushed
the
ericgustin/too-1932-resource-registry
branch
from
August 26, 2026 20:32
32e510b to
946771a
Compare
EricGustin
force-pushed
the
ericgustin/too-1933-qualify-resource-uris
branch
from
August 26, 2026 20:32
0827a8e to
720cf1c
Compare
EricGustin
marked this pull request as ready for review
August 26, 2026 21:20
Greptile SummaryThe PR adds toolkit- and version-qualified resource declarations while preserving the resource scheme.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| libs/arcade-core/arcade_core/resources.py | Adds resource declaration qualification and registry integration without an accepted follow-up finding. |
| libs/arcade-core/pyproject.toml | Applies the expected minor version bump for the additive public API. |
| libs/tests/core/test_resource_uri_qualification.py | Covers URI identity, normalization, traversal rejection, scheme preservation, and registry URI consistency. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
D[ResourceDeclaration] --> Q[qualify]
I[Toolkit name and version] --> Q
Q --> U[Qualified URI]
U --> R[ResourceRegistry.add]
C[Resource contents] --> R
R --> L[Listing and contents share URI]
Reviews (3): Last reviewed commit: "feat(core): qualify resource URIs by too..." | Re-trigger Greptile
EricGustin
force-pushed
the
ericgustin/too-1932-resource-registry
branch
from
August 26, 2026 22:08
946771a to
590e7f4
Compare
EricGustin
force-pushed
the
ericgustin/too-1933-qualify-resource-uris
branch
from
August 26, 2026 22:08
720cf1c to
844ae64
Compare
EricGustin
force-pushed
the
ericgustin/too-1932-resource-registry
branch
from
August 27, 2026 00:15
590e7f4 to
ccc7675
Compare
EricGustin
force-pushed
the
ericgustin/too-1933-qualify-resource-uris
branch
from
August 27, 2026 00:15
844ae64 to
b9f2ad9
Compare
A resource a toolkit declares is registered at ui://<Toolkit>/<version>/<path>. The author writes the path; the URI is derived and never typed by hand. Two collisions close here. Two toolkits packed into one worker image could otherwise claim the same URI, which the toolkit segment settles. And the same toolkit can be installed at two versions across two workers, so without the version segment a version 8 tool and a version 7 tool both point at ui://Gmail/draft.html; a gateway that picks the wrong worker then renders a version 7 interface for a version 8 tool, with nothing reporting an error. The scheme is carried through and never replaced. A host that renders a tool's interface requires ui:// and throws on anything else, so a prefix-replacing qualifier breaks rendering outright. Qualification lives inside the registry because that is the only point where a declaration and the toolkit's identity are both in scope. Traversing paths are refused rather than normalized away.
EricGustin
force-pushed
the
ericgustin/too-1932-resource-registry
branch
from
August 27, 2026 15:35
ccc7675 to
0c3d732
Compare
EricGustin
force-pushed
the
ericgustin/too-1933-qualify-resource-uris
branch
from
August 27, 2026 15:35
b9f2ad9 to
474a19a
Compare
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
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.
Summary
A resource a toolkit declares gets registered at
ui://<Toolkit>/<version>/<path>. The author writes the path. The URI is derived at registration and never typed by hand.Part 3 of 6. Stacked on #918.
Resolves: https://linear.app/arcadedev/issue/TOO-1933
Design decisions
Two things can collide, and each segment closes one of them.
One worker can host many toolkits, so two of them could otherwise both claim
ui://draft-review.html. The toolkit segment settles that, and with it in place no cross-toolkit collision is possible at all.The version segment handles a subtler case. The same toolkit can be installed at two versions across two workers. Strip the version and a v8 tool and a v7 tool both resolve to
ui://Gmail/draft.html, so a gateway that picks the wrong worker renders a v7 interface for a v8 tool and nothing anywhere reports an error. That failure is silent, and it surfaces to whoever hits it as a rendering bug with no obvious cause. Worth a path segment.The scheme is carried through and never replaced. A host that renders a tool's interface requires
ui://and throws on anything else, so a qualifier that swaps the prefix (arcade://source/ui://...) breaks rendering outright. There is a test pinning that.Qualification happens inside the registry, since that is the only place a declaration and the toolkit's identity are both in scope. Traversing paths (
../) get refused instead of normalized away.Scope
In scope: making a URI unique within one worker.
Not in scope: making it unique across backing servers. That belongs to whatever serves these onward. One note for whoever builds it: a qualifier at that level has to apply unconditionally rather than skipping URIs that already look qualified, because a remote MCP server emits this same authority-segment shape and no amount of inspection tells the two apart. Two qualifiers at two levels nest without trouble.
Test plan
libs/tests/core/test_resource_uri_qualification.pyuv run pytest libs/tests: 3807 passed, 1 skippeduv run mypy .clean in each of the four librariesruff checkandruff format --checkclean on every touched fileAuthor checklist
Before moving this PR from Draft to Ready for Review:
make checkandmake testare green locally; CI is expected to passNote
Medium Risk
Changes how resource URIs are formed and registered—wrong qualification could break UI rendering or cache keys—but validation and tests target collision and traversal cases.
Overview
Toolkit authors declare resources by path only; registration now derives URIs as
ui://<Toolkit>/<version>/<path>so multiple toolkits on one worker and different toolkit versions do not collide silently.arcade-core adds
UI_SCHEME,qualify(),ResourceDeclaration,InvalidResourcePathError, andResourceRegistry.declare()(qualification at register time). Paths are normalized (slash handling) and reject../.traversal; schemes are preserved (not rewritten to another prefix). Package version bumps to 4.14.0.New tests in
test_resource_uri_qualification.pycover qualification rules, registrydeclare, and listing vs contents URI consistency for caching.Reviewed by Cursor Bugbot for commit 474a19a. Bugbot is set up for automated code reviews on this repo. Configure here.