ryer.io

AI Catalog Consumer Enablement: Permission Matrix & FF Bug Trace

TL;DR

  • Mapped out full behavior matrix for enabling agents/flows across Developer, Maintainer, and Owner/Admin roles, in Explore vs Project namespace, with the feature flag on/off
  • FF on: TLG Owner and Project Maintainer become identical (FF levels the playing field); Developers are always blocked
  • FF off: only TLG Owners succeed; Project Maintainers can open the form but backend rejects their submission (the UX problem the FF is meant to solve)
  • Private items always show static pre-selected fields regardless of role/FF; only the submit button’s enabled state changes
  • Traced a bug where the MR added a new project-only dropdown template path gated by canEnable/isProjectLevelEnablement, but never updated handleSubmit or targetType, so Explore-level submissions still send a null groupId and fail the backend mutation

Test Matrix: Roles x Namespace x Feature Flag

Built out two versions of a matrix covering Developer, Maintainer, and Owner/Admin roles across Explore and Project namespaces, for both Agent and Flow item types, with the feature flag on and off. Key patterns: with FF on, TLG Owner and Project Maintainer behave identically — the FF completely levels the playing field — while Developers are consistently blocked (canEnable stays false across all 8 combinations, rows 9-12 and 21-24). With FF off, only TLG Owners succeed (rows 13-16); Project Maintainers can see and fill in the form but the backend rejects them (rows 17-20) — this is exactly the UX problem the FF is meant to solve. Private items always render static fields pre-selected from the item’s own project/group regardless of role or FF; the only variable is whether the submit button is enabled. Extended the matrix further with columns for enable button visibility from the show screen, whether the modal is openable, and the specific warning text shown (full warning vs. reduced warning vs. private alert).

Root Cause Trace: Template vs Submit Handler Mismatch

Reconstructed the bug trace as if working only from the MR diff. The MR adds a new template branch in ai_catalog_item_consumer_modal.vue for isProjectLevelEnablement && canEnable, rendering a project-only dropdown, and threads canEnable through as a prop — but handleSubmit is never touched. Tracing handleSubmit shows it branches on enableGroupAndProject and isTargetTypeGroup, and isTargetTypeGroup is derived from targetType, which depends only on showEnableFromGlobal (true at Explore level) — never on the feature flag. So at Explore level with the FF on, the template renders a project dropdown (setting projectId), but submit still treats it as a group target and sends groupId: null. Checked enableModalProps in ai_catalog_item_actions.vue and confirmed enableGroupAndProject still defaults to true, so handleSubmit takes the branch that sends { target: { groupId: this.groupId }, projectId: this.projectId } — still with a null groupId. Followed this payload to the show pages (ai_catalog_agents_show.vue, ai_catalog_flows_show.vue), which call enableForGroupAndProject: the first mutation tries to create a group consumer with target.groupId: null and fails because the backend’s one_of input requires a valid ID, so the second mutation is never reached. Root cause: the MR added a new rendering path without a corresponding submission path — targetType still ignores the FF entirely, so Explore-level enablement is always submitted as a group target even when the UI now collects a project instead. The method throughout was to follow the data from user interaction to API call, checking at each hop whether the MR’s changes kept the chain consistent — the break was between the template (changed) and the submit handler (not changed).