Skip to content

feat(agents): schema-mirror install flow for template agents#353

Closed
buremba wants to merge 3 commits into
feat/schema-mirror-tracking-colsfrom
feat/schema-mirror-install-flow
Closed

feat(agents): schema-mirror install flow for template agents#353
buremba wants to merge 3 commits into
feat/schema-mirror-tracking-colsfrom
feat/schema-mirror-install-flow

Conversation

@buremba
Copy link
Copy Markdown
Member

@buremba buremba commented Apr 25, 2026

Summary

New `packages/owletto-backend/src/agents/install.ts` with `installAgentFromTemplate()` and `resyncInstalledAgent()`. Creates an agent row in the target org with `template_agent_id` set, then mirrors the template org's `entity_types` and `entity_relationship_types` into the target org tagged `managed_by_template_agent_id` + `source_template_org_id` (columns added by #351).

  • Idempotent — re-install updates the same agent + upserts the mirror rows.
  • Safe — refuses to overwrite user-authored schema rows (`managed_by_template_agent_id IS NULL`) or rows owned by a different template agent.
  • Transactional — agent insert + all schema mirroring in one `sql.begin` block.

Deferred to follow-up PRs: mirroring `event_classifiers` (entity-scoped complexity) and `watchers` (needs `watcher_versions` + reaction_script handling).

Stacked on

Targets `feat/schema-mirror-tracking-cols` (#351). Rebase onto main once #351 merges.

Test plan

  • Pre-commit Biome + tsc pass.
  • Integration test in `src/tests/integration/agents/install.test.ts` exercises: fresh install, managed_by tagging, idempotency, re-sync propagation, self-install refusal, user-authored overwrite refusal.
  • Run integration suite against a configured `DATABASE_URL` (test DB).

New installAgentFromTemplate(templateAgentId, targetOrganizationId, userId)
creates an agent row in the target org with template_agent_id set, then
mirrors the template org's entity_types and entity_relationship_types
into the target org tagged managed_by_template_agent_id + source_template_org_id.

Core properties:
- Idempotent. Re-running against the same target updates rather than
  creating duplicates.
- Safe. The mirror never overwrites rows the user authored directly
  (managed_by_template_agent_id IS NULL). Slug collisions with user rows
  or with a different template agent abort with a descriptive error.
- Re-syncable. resyncInstalledAgent() lets template schema evolution
  propagate to every installed instance.

Watchers and classifiers are deferred to a follow-up — watchers need the
watcher_versions + reaction_script dance, classifiers are scoped per-
entity so they interact with entity mirroring.

Paired with an integration test under __tests__/integration/agents/ that
covers: create on first install, idempotency, managed_by tagging, re-sync
propagation, refusal to install into the template's own org, refusal to
overwrite user-authored rows.
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@buremba buremba added the skip-size-check Bypass PR size gate for intentionally large single-concern changes label Apr 25, 2026
Defense in depth: previously installAgentFromTemplate trusted the caller
to have already authorised the user against the target org. The public
install route does enforce that (it derives targetOrganizationId from
the authenticated user's personal org), but any future caller could
bypass it.

Add an explicit membership lookup against the "member" table inside
installAgentFromTemplate. Refuses when:
- user has no member row in the target org
- user is a plain member (only owner/admin can install)

Adds two tests for the new error paths.
@buremba
Copy link
Copy Markdown
Member Author

buremba commented Apr 25, 2026

Closing per docs/plans/world-model.md — installAgentFromTemplate's schema mirroring is replaced by reference, not copy. Templates become entities of type agent_template in a public_catalog org with uses_catalog relationships; the user's agent reads vocabulary from those catalogs at boot via a schema search path.

Install becomes ~30 lines: insert agent row in user's tenant + provision $member (#359). The 1221 LOC of mirror logic + idempotency + user-authored protection all evaporate.

@buremba buremba closed this Apr 25, 2026
@buremba buremba deleted the feat/schema-mirror-install-flow branch April 26, 2026 16:36
@buremba buremba restored the feat/schema-mirror-install-flow branch May 12, 2026 00:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-size-check Bypass PR size gate for intentionally large single-concern changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant