Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix: allow extension loops to call owned tools - #503

Merged
pedronauck merged 7 commits into
compozy:mainfrom
franciscpd:fix/extension-owned-loop-tools
Aug 31, 2026
Merged

fix: allow extension loops to call owned tools#503
pedronauck merged 7 commits into
compozy:mainfrom
franciscpd:fix/extension-owned-loop-tools

Conversation

@franciscpd

@franciscpd franciscpd commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

What & why

Code-backed extensions can contribute both Loops and tools, but the default external-source policy prevented a contributed Loop from resolving tools owned by that same extension.

This change preserves the canonical manifest owner through resource loading, compilation, executed snapshots, and hydration. During daemon execution it adds only the exact same-owner extension source to the normal allow set; it never grants trusted-source status, and foreign extension sources remain denied. Loop schema compilation also snapshots the operator registry once per compilation instead of repeatedly projecting it.

Closes #501

Codex co-wrote the implementation. I independently reviewed the result and verified it locally.

How you verified it

  • make gate
  • make codegen-check
  • Focused race suites for extension resources, Loop snapshots, daemon catalog/schema projection, and tool policy resolution
  • Isolated code-backed extension smoke: its contributed Loop compiled, started, and dispatched its own action without unknown_action_kind
  • Independent read-only code review: approved with no remaining findings

Impact

No CLI, HTTP/UDS, config.toml, database migration, or web UI contract changes. The change is limited to daemon-side Loop provenance and tool-policy resolution. Public Loop extension documentation and QA coverage are updated.


  • make gate passes locally; this PR is delivered only after its required CI checks are green
  • New or changed behavior is covered by tests, or I explained above why not
  • If an agent wrote or co-wrote this, I named it above and verified the result myself

Summary by CodeRabbit

  • New Features

    • Added extension provenance tracking to Loop resources and execution snapshots.
    • Preserved extension ownership across Loop resolution, hydration, and action execution.
    • Restricted Loop tools to those owned by the extension that installed the Loop.
    • Improved tool schema loading efficiency by caching registry data.
  • Bug Fixes

    • Prevented unauthorized or forged extension-owned tools from being resolved.
    • Ensured extension ownership is consistently normalized and validated.
    • Improved extension installation reliability during temporary database write contention.

@vercel

vercel Bot commented Aug 28, 2026

Copy link
Copy Markdown

@franciscpd is attempting to deploy a commit to the Compozy Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 03990471-ee67-471d-a3c5-bc87860a4e96

📥 Commits

Reviewing files that changed from the base of the PR and between 90e6a1e and d5ca7db.

⛔ Files ignored due to path filters (1)
  • web/e2e/__tests__/tasks.spec.ts is excluded by !web/e2e/**
📒 Files selected for processing (2)
  • internal/extension/registry_install.go
  • internal/extension/registry_test.go

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


Walkthrough

The change preserves extension provenance on Loop resources, resolved definitions, and execution snapshots. Daemon execution passes the trusted extension owner to policy resolution. Policy resolution grants only the matching extension source. Tool schemas load once and remain cached. Extension installation persistence uses managed write transactions.

Changes

Extension-owned Loop tools

Layer / File(s) Summary
Provenance contracts and resource loading
internal/loop/resource_spec.go, internal/loop/resource_spec_validation.go, internal/extension/manager_resource_loading.go, internal/extension/loop_resources_test.go, internal/loop/compiler.go, internal/daemon/task_runtime_boot_roles.go, internal/daemon/loop_api_catalog_test.go
Resource specs, compiled definitions, and resolved Loop definitions now carry normalized extension provenance. Resource loading records the extension owner and registry slug.
Executed-definition provenance
internal/loop/executed_definition_snapshot.go, internal/loop/executed_definition_hydrate.go, internal/loop/coordinator_snapshot_test.go
Executed-definition snapshots serialize extension provenance, and hydration restores the trimmed values.
Cached tool schema projection
internal/daemon/loop_tool_schema_source.go, internal/daemon/loop_tool_schema_source_test.go
The daemon lists operator-scoped tool schemas once, caches them, and returns cloned schemas without per-request registry lookups.
Trusted owner propagation and policy grant
internal/tools/policy_resolver.go, internal/loop/coordinator_action.go, internal/loop/coordinator_test.go, internal/daemon/tool_policy_resolver.go, internal/daemon/loop_tool_schema_source_test.go, internal/daemon/loop_read_cli_e2e_integration_test.go
Action execution places the resolved extension owner in context. Daemon policy resolution grants the exact owner extension source. Tests cover same-owner authorization, foreign and forged owners, and the human-gate Loop fixture.

Registry persistence retry

Layer / File(s) Summary
Managed installation persistence
internal/extension/registry_install.go, internal/extension/registry_test.go
Extension installation writes now use store.ExecuteWrite. A regression test verifies persistence after a transient SQLite busy condition.

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

Merge Risk: ⚪ Minimal · up to d5ca7

Extension-contributed loops can now call tools owned by the same extension while foreign extension tools remain denied; no actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant LoopResource
  participant ResolveLoop
  participant ExecuteActionRun
  participant ToolPolicyResolver
  participant loopToolSchemaSource
  LoopResource->>ResolveLoop: provide extension provenance
  ResolveLoop->>ExecuteActionRun: return resolved definition
  ExecuteActionRun->>ToolPolicyResolver: attach trusted extension owner
  ToolPolicyResolver->>loopToolSchemaSource: load or read cached tool schema
  loopToolSchemaSource-->>ToolPolicyResolver: return schema
  ToolPolicyResolver-->>ExecuteActionRun: authorize same-owner tool
Loading

Suggested reviewers: pedronauck

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Most changes support issue #501, but internal/extension/registry_install.go and internal/extension/registry_test.go add unrelated SQLite busy-retry persistence behavior. This behavior is not part of e… Remove the SQLite busy-retry persistence changes and their regression test, or link an issue that explicitly requires this installation persistence behavior.
Docstring Coverage ⚠️ Warning Docstring coverage is 13.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 30 functions across 19 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary change: allowing extension-owned Loops to call tools owned by the same extension.
Linked Issues check ✅ Passed The changes preserve extension ownership through resource loading, compilation, snapshots, and hydration. Daemon policy grants only the exact same-owner extension source. Tests cover registry projecti…
Full details: Linked Issues check

Explanation

The changes preserve extension ownership through resource loading, compilation, snapshots, and hydration. Daemon policy grants only the exact same-owner extension source. Tests cover registry projection, context propagation, cancellation, same-owner authorization, foreign tools, forged ownership, and snapshot round-tripping. The provided evidence supports the requirements in issue #501.

Full details: Out of Scope Changes check

Explanation

Most changes support issue #501, but internal/extension/registry_install.go and internal/extension/registry_test.go add unrelated SQLite busy-retry persistence behavior. This behavior is not part of extension-owned Loop tool authorization.

✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@franciscpd
franciscpd marked this pull request as ready for review August 29, 2026 18:45
@franciscpd
franciscpd requested a review from pedronauck as a code owner August 29, 2026 18:45
@greptile-apps

greptile-apps Bot commented Aug 29, 2026

Copy link
Copy Markdown

Greptile Summary

The PR preserves extension ownership through Loop loading, compilation, snapshots, hydration, and execution so extension-owned Loops can resolve tools from the same owner without trusting or allowing foreign extension sources.

  • Adds canonical extension provenance to Loop resources and executed definitions.
  • Adds an exact-owner source grant during daemon action resolution.
  • Snapshots operator tool schemas once per compilation.
  • Expands runtime, policy, lifecycle, documentation, and QA coverage.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains.

No blocking failure remains.

Important Files Changed

Filename Overview
internal/extension/manager_resource_loading.go Carries canonical extension ownership into loaded Loop resources.
internal/loop/executed_definition_snapshot.go Persists Loop extension provenance in the executed definition snapshot.
internal/loop/executed_definition_hydrate.go Restores persisted extension provenance when hydrating a run.
internal/daemon/tool_policy_resolver.go Adds the exact trusted-context owner to allowed sources without granting trusted-source status.
internal/daemon/loop_tool_schema_source.go Replaces repeated schema lookups with one immutable operator registry projection per compiler source.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  E[Extension manifest owner] --> R[Loop resource]
  R --> C[Compiled definition]
  C --> S[Executed snapshot]
  S --> H[Hydrated run]
  H --> P[Daemon policy resolver]
  P --> O[Allow exact owner source]
  P --> F[Deny foreign extension sources]
  O --> T[Resolve same-owner tool]
Loading

Reviews (9): Last reviewed commit: "fix: retry extension lifecycle writes" | Re-trigger Greptile

Comment thread docs/qa/scenarios/LP-extension-owned-loop-tool-policy.md
coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 29, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 29, 2026
Preserve trusted extension ownership through Loop snapshots and grant only the exact same-owner extension source during daemon execution.

Refs compozy#501
@franciscpd
franciscpd force-pushed the fix/extension-owned-loop-tools branch from eff54a1 to 15f6671 Compare August 29, 2026 21:04
@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 30, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 30, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 30, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 30, 2026
bug_ids:
fix_status:
retest_status:
fix_commits:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 QA evidence remains local-only

When a reviewer or later QA run inspects this passed scenario from another checkout, the absolute /home/francisross/dev/qa-labs/... path cannot be opened or restored, so the result and teardown artifacts do not provide durable verification of the recorded verdict.

Context Used: CLAUDE.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@franciscpd
franciscpd marked this pull request as draft August 30, 2026 14:38
@franciscpd
franciscpd marked this pull request as ready for review August 30, 2026 19:47
@pedronauck
pedronauck merged commit 01a1f24 into compozy:main Aug 31, 2026
39 of 40 checks passed
This was referenced Aug 30, 2026
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.

[Core] Allow extension-owned Loops to call same-extension tools

2 participants