feat: keep withheld resources as slim reference mappings - #300
Merged
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Ruari-Phipps
force-pushed
the
feat/slim-resource-references
branch
from
September 1, 2026 11:06
e2e7451 to
9a9aa63
Compare
This comment has been minimized.
This comment has been minimized.
jamesosullivan-polyai
approved these changes
Sep 1, 2026
Dropping a withheld resource type entirely leaves every
{{entity:...}}-style reference to it rendering as a raw id, and the
file then looks locally modified on every command. Withheld resources
whose ids appear inside resources gated on a different permission are
now kept as identity-only stubs, separated out of the resource map into
slim_resources - a list of ResourceMapping that resolves references but
is never iterated for a file, saved, or pushed.
- ResourceMapping gained to_dict/from_dict, storing resource_type by
its registered name, so slim mappings persist in the status file. An
unregistered type is dropped on read rather than raising.
- Slim resources are excluded from file_structure_info - they have no
file on disk, so a baseline entry would make find_new_kept_deleted
report them deleted on every run.
- pull_resources, pull_deployment_resources, pull_branch_resources,
get_template_resources, get_remote_resources_by_name and
_resolve_branch_fork_point all return their slim mappings alongside
the resource map, and every caller was updated to match.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
pull_project overwrote self.slim_resources with the incoming list before _update_pulled_resources built the original resource mappings, so the baseline resolved references against the incoming slim set. The two diverge when a withheld resource was renamed remotely or permissions changed - the baseline then renders with the new name while the disk file carries the old one, a phantom local change at merge time. _update_pulled_resources now takes both slim lists explicitly and every caller passes the list that matches each side. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
RESOURCE_NAME_TO_CLASS.get("variables") returning None would make the
isinstance check raise TypeError, and .get("functions") returning None
fails the other way - silently degrading to "functions are not slim",
which is the unsafe direction. Import the classes and use them directly;
the deferred import avoids the module-level cycle.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
FlowConfig can never be slim - a filtered flows slice returns no flow configs at all - so the string-typed special cases were unreachable. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The rationale lived only in a test docstring; the one non-mechanical rule in _filter_slim_resources deserves its why next to it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ResourceMapping.from_dict called cls(**data) on a dict straight off the status file. One unexpected key - a hand edit, or a field written by a newer ADK - raised TypeError and killed every command. Unknown keys are now dropped and an entry missing required fields loses that one mapping instead of aborting, matching how an unregistered resource type is already handled. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ruari-Phipps
force-pushed
the
feat/slim-resource-references
branch
from
September 1, 2026 14:35
9a9aa63 to
e9d661a
Compare
Ruari-Phipps
enabled auto-merge (squash)
September 1, 2026 14:36
Contributor
Coverage Report
Changed file coverage
|
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
Withheld resources whose ids appear inside resources gated on a different permission
are kept as identity-only mappings rather than dropped, so
{{entity:...}}-stylereferences to them still resolve to a name. They live in
slim_resources, a list ofResourceMappingthat resolves references but is never iterated for a file, saved, orpushed.
Motivation
With #299 alone, a restricted reader's pull succeeds but every reference to a withheld
resource renders as a raw id — and because the id round-trips differently than the name,
the file looks locally modified on every command. The mapping also has to survive in the
status file: every command other than pull rehydrates from it, so a slim resource not
written there is gone by the next command.
Changes
from_projectionfor entities, functions, handoffs, SMS templates, translations,variants and variant attributes returns identity-only stubs (
slim=True) forauth-filtered slices;
load_resources_from_projectionseparates them out of theresource map into a list of
ResourceMapping.variableUpdateis gated on adifferent permission than functions, so the API would accept a reference graph rebuilt
from functions the user cannot see.
ResourceMappinggainedto_dict/from_dict, storingresource_typeby itsregistered name so slim mappings persist in the status file. An unregistered type is
dropped on read rather than raising.
file_structure_info— they have no file on disk, soa baseline entry would make
find_new_kept_deletedreport them deleted on every run.pull_resources,pull_deployment_resources,pull_branch_resources,get_template_resources,get_remote_resources_by_nameand_resolve_branch_fork_pointall return their slim mappings alongside the resourcemap, and every caller (pull, push, status, diff, branch diff, validate, sync-ids) was
updated to resolve references against them.
withheld, and cache/disk agreement after a pull.
Test strategy
poly <command>)Checklist
ruff check .andruff format --check .passpytestpasses (1453 passed, 165 subtests)polyCLI interface (or migration path documented)