Skip to content

[SC-16888] Reconcile stale agents on sync to prune archived/deleted VM records#124

Open
even-steven wants to merge 1 commit into
mainfrom
stevenchand/sc-16888/atryum-auto-sync-charters-from-validmind
Open

[SC-16888] Reconcile stale agents on sync to prune archived/deleted VM records#124
even-steven wants to merge 1 commit into
mainfrom
stevenchand/sc-16888/atryum-auto-sync-charters-from-validmind

Conversation

@even-steven

Copy link
Copy Markdown
Contributor

What and why?

Previously, archiving or deleting an inventory record in ValidMind left the corresponding agent row in Atryum's database indefinitely — the sync only upserted, never removed. The agent remained visible in the Atryum UI until a user changed the org or record type in Settings (which triggers DeleteSynced).

This PR adds reconciliation to every sync run: after upserting the active records returned from ValidMind, any synced agent for the configured org whose vm_cuid is no longer in the pull is deleted. This covers records archived or deleted in ValidMind.

Safety: agents with active managed agent bindings (managed_agent_bindings FK → agents.id ON DELETE CASCADE) are exempted from pruning — their vm_cuid is added to keepCUIDs before the delete so binding configuration is not accidentally destroyed.

Companion PR in the backend repo adds the CRUD-event triggers that fire the sync automatically: validmind/backend#3330

How to test

  1. Configure Atryum with a ValidMind org and record type.
  2. Ensure at least one inventory record is synced as an agent.
  3. Archive or delete that record in ValidMind.
  4. Trigger a sync (manually via the Sync button, or wait for startup).
  5. Confirm the agent is removed from the Atryum Agents list.
  6. Confirm that an agent with managed agent bindings is not removed even if its VM record is archived.

What needs special review?

  • ListVMCUIDsWithBindings uses a raw SQL query (agents WHERE id IN (SELECT DISTINCT agent_cuid FROM managed_agent_bindings)). This works for both SQLite and PostgreSQL dialects but bypasses the squirrel query builder — intentional for the subquery pattern.
  • If ListVMCUIDsWithBindings errors, the entire prune step is skipped (logged). This is a safe degradation: stale agents linger until the next successful sync rather than risking accidental deletion.

Dependencies, breaking changes, and deployment notes

  • Companion PR required in validmind/backend: validmind/backend#3330 — adds the CRUD event triggers that call Atryum's sync endpoint automatically.
  • No new migrations, no config changes, no API surface changes.
  • Startup sync now also prunes stale agents, so deploying this binary alone (without the backend PR) is safe and beneficial.

Release notes

Archived or deleted ValidMind inventory records are now automatically removed from Atryum's agent list on the next sync, keeping the two systems consistent without manual intervention.

Made with Cursor

…eted records

After each sync pull from ValidMind, delete synced agent rows whose
vm_cuid is no longer present in the response (archived or deleted in VM).

- AgentsRepo.DeleteSyncedStaleForOrg: deletes synced agents for the
  given org whose vm_cuid is not in keepCUIDs. If keepCUIDs is empty,
  removes all synced agents for the org. Manually-created agents
  (empty vm_organization_cuid) are never touched.
- AgentsRepo.ListVMCUIDsWithBindings: returns vm_cuids of agents with
  at least one managed_agent_binding row. These are added to keepCUIDs
  before pruning so their ON DELETE CASCADE binding config is preserved.
- syncAgents now collects activeCUIDs from successful upserts, fetches
  boundCUIDs, and calls DeleteSyncedStaleForOrg with the union. If the
  bindings query fails, the prune step is skipped (safe degradation).

Co-authored-by: Cursor <cursoragent@cursor.com>
@even-steven even-steven added the enhancement New feature or request label Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant