Skip to content

Owners on create: your teams one click away, the owner rules that will run said on the review, and an owner rule's Creator's Team - #5209

Merged
simlarsen merged 17 commits into
masterfrom
claude/creator-team-owner
Oct 23, 2026
Merged

simlarsen merged 17 commits into
masterfrom
claude/creator-team-owner

Conversation

@simlarsen

@simlarsen simlarsen commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

What was asked

  • Maintainer: "On Alert/Incident creation - I don't see a way to add the team of the incident creator as an owner. Can you please check if this is true, and if this is true, can you please build that option as well? We can have that and more, so it is not visible by default on the form."
  • Customer: the confirmation step never said which owner rules would run ("tell me either the name of the rules that will apply, or the action it will take - Team_XYZ will be added"), and: how do I automatically add (a) the incident creator and (b) the team the incident creator belongs to as owners?

What I found

  • True: Declare Incident and Create Alert had no Owners field at all (it was removed in February, when roles came). Owners from an incident template were sent without being shown. Create Incident Episode had no Owners field either.
  • (a) is already the case: whoever creates an incident or an alert is made an owner when it is saved (DatabaseService.autoOwnerOnCreate, incidents and alerts are operational resources). Nothing said so on the form.
  • Bug: Create Alert Episode has asked for owners for a while, but AlertEpisodeService never added them - the picks were dropped.
  • Owner rules ran only after the create, and nothing before it said what they would do.

What changes

On the create forms (Declare Incident, Create Alert, Create Incident Episode; Create Alert Episode keeps its On-Call & Owners step)

  • Owners, one people-and-teams picker, folded under More fields at the end of the first step - not visible by default. Its line says what is already true: "You become an owner when you declare it. Add your team, or anyone else who should own it."
  • Under the picker, the creator's own teams are one click away: Your teams: + Database + Members + Platform · Add all. Nothing is picked by itself (Members and Owners are teams too).
  • The review step always has an Owners row: the owners picked (or "Nobody else picked."), then Added by owner rules - each owner rule that will run, by name, with the people and teams it will add (the customer's "Team_XYZ will be added").
  • That list comes from the server: POST /api/<incident|alert|incident-episode|alert-episode>/owner-rule-preview runs the same planRules the create runs (the engines now plan first, then write), for the draft as the form holds it - title, description, severity, labels, monitors and other resources. Nothing is guessed in the browser. While it asks, the row says so; if it fails, it says the rules still run when the incident is created, and creating is never blocked. Someone who may not read the owner rules is told nothing about them (the route answers as a read of the rule model, project-scoped, and refuses ids from another project).
  • Declaring from a template now starts the field with the template's owners, visible and editable, instead of sending them unseen.
  • The picks travel as ownerUsers / ownerTeams misc data, as the API already took them: the server checks the creator may add them before anything is saved, and adds them once the event exists. Both episode services now do this too, which fixes the dropped alert episode owners.

On incident and alert owner rules

  • New Creator's Team list (creatorTeams), last in the Inherit Owners fold of the rule's Owners step: of the teams listed, each one the person who created the event is a member of becomes an owner too. The fold's folded line now names it ("Optionally assign owners from related entities, or the creator's team, to the incident.").
  • A rule that lists only a team there adds something: it saves, is named "Add the creator's team as an owner" until you type a name, is not marked Adds nothing, and the API refusal for an empty rule names the list ("...a team in Creator's Teams, or turn on an Inherit Owners switch.").
  • An incident or alert made by a monitor, a workflow, a form or an API key has no creator, so it gets none of these teams. A creator who has left the project is in none of its teams.
  • Migration 1806300000000-AddOwnerRuleCreatorTeams (generated): two new join tables, IncidentOwnerRuleCreatorTeam and AlertOwnerRuleCreatorTeam, indexes and foreign keys on empty tables, nothing to backfill. Ran all migrations on a fresh Postgres: no schema drift.

Option on the form vs rule target: which one when

Owners on the create form Creator's Team on an owner rule
Who decides the person creating it, each time a rule author, once, for everyone
What it adds anyone picked, with their own teams one click away of the teams the rule lists, the ones the creator is in
When only when someone opens More fields and picks every matching incident or alert a person creates
Visible folded under More fields in the rule's Inherit Owners fold; the create form's review lists the rule and the team it will add

There is no "add the creator" rule target: the creator is always made an owner of an incident or alert already, so such a switch could only ever be on. There is no "every team of the creator" switch either: people are invited into the project's Members team by default (and teams also carry permissions), so it would make Members - everyone - an owner of every incident someone declares. A rule names which teams count instead.

What existing customers will notice

  • Declare Incident, Create Alert and Create Incident Episode have one more item under More fields; the review step has an Owners row. Nobody's form opens differently.
  • Owner rules saved before keep adding exactly what they added; the new list starts empty.
  • Alert episodes created with owners now actually get them.
  • Owners from an incident template now show in the field before declaring.

Tests

  • Server: OwnerRulePlan, CreatorTeams, InheritedOwners, OwnerRulePreviewBuilder, OwnerRulePreviewRoute (permissions, project scoping, refusals, cache headers), EpisodeOwnersPickedOnCreate (both episode services: checked before save, added after, before the rules run), the rule engine suites (plan = writes), OwnerRuleAssignment, empty-rule refusals, RuleAction.
  • Dashboard: OwnersOnCreateRules, OwnersOnCreateForm (field, suggestions, Add all, review row states), template owners, CreateFormsInitialState, DeclareFormsAdvancedRender, ResourceRuleForm / ResourceRuleFormsRender, RuleTablesAddsNothing, BasicFormPeoplePicker.
  • Guards: form/route guards taught the Creator's Team and the preview routes (ResourceRuleFormsGuard, OwnersFieldGuard, DeclareAndCreateFormsGuard, ExpiredSessionRouteGuards, ProjectScopedApiTenantHeader, ...).
  • Browser (offline fixture, Chromium, 22 tests): packages/E2E/OwnersOnCreate - npm run test-owners-on-create-ui, added to CI group 5 with its screenshots uploaded. The real Declare Incident, Create Alert and owner rules pages over an in-memory project: folded Owners, Your teams, Add all, the review's rules and what the preview is asked, what a create sends, slow / failing / denied previews, the rule form's Creator's Team (save, Edit reads it back, Adds nothing), at 1280 and 390 px, dark, German.
  • Docs, 17 languages: Declaring an Incident (Owners bullet, "Who will own it", the API), Alerts, Alert Episodes, Label and Owner Rules ("The creator's team", the new refusal), the incident owners page and both rules settings pages.

What ran

  • Common: every suite above, npx jest Guard (162 suites), the listed gates (RelationListReadCoverage, PlanGatedTableLeftovers, PageSearchIndexCovers*, Update/DeleteChecksReadHeldRows, HookWritesCallersMayMake, ListOrderColumnModels, PermissionCatalogueCoverage, SchemaMigrationsOnlineDdl/Ordering), npm run compile, npm run compile-tests.
  • App: compile, root tests, Short/Card description guards, NormalizeListOrder, the docs suites for every page touched plus the all-pages ones, docs:check-anchors, i18n:check / i18n:extract / i18n:validate; no cross-package imports in tsc --listFiles.
  • E2E: the whole new suite, 22/22.
  • Migrations from scratch on Postgres 15 + the schema drift check.
  • Prettier and ESLint on every changed file; the regex timing checker (no new non-linear pattern outside tests).

UI review

What I looked at. The real pages in the offline fixture (Chromium, Inter, Tailwind), at 1280 and 390 px, light and dark, English and German: Declare Incident, Create Alert, Create Incident Episode and Create Alert Episode - the Owners field folded and open, Your teams for someone in no team, one, three and eight teams (long names), and the summary's Owners row with rules, with owners already picked, with every owner picked, while it checks, when it fails, when the person may not read the rules, and with nobody picked. The incident and alert owner rules pages: create, edit, a rule's own page, the table's Adds nothing. Also the feed note a creator's team rule writes, the in-app help on both rules pages, and the English and German docs pages.

What I changed, and why.

  • A rule's line on the summary no longer repeats owners already picked. With Platform picked, a rule that brings Platform and Database read "Platform, Database" right under "Platform". Each line now names only the people and teams the rule adds that are not owners yet. It leaves out the owners picked and the person creating an incident or alert, since OneUptime adds an owner only once. When that leaves nobody, the line says Everyone it adds is already an owner. The rule still has its line, because it still runs. (getOwnersNewFromRule)
  • A master admin is no longer told they become an owner. OneUptime never makes a master admin the owner of what they create (DatabaseService.autoOwnerOnCreate), and the first person to sign up on a self-hosted install is one. They now read Add your team, or anyone else who should own it., and the summary says Nobody picked. A rule that names them still lists them.
  • The summary's rule-name column is wide enough for the default name Add the creator's team as an owner to fit on one line (w-56 to w-64, measured at 237 px in Inter).
  • The summary's rules list is labelled by its Added by owner rules heading, so a screen reader announces what the list is.
  • The incident and alert feed note now reads "...is a member of them." instead of ending on "...is a member."
  • The help on both owner rules pages describes the creator's team in plainer words.
  • FormSummary now gives each step a key. React warned "Each child in a list should have a unique key" on every stepped summary, on every create form.
  • Two new Dashboard strings, translated in all 17 locales.

Left alone on purpose.

  • Create Alert Episode keeps Owners visible on its On-Call & Owners step, while Create Incident Episode folds Owners under More fields as Declare Incident does. Moving the alert episode's field would change a form people already use.
  • The Inherit Owners fold line keeps the builder's words, which match its sibling Inherit Labels lines.
  • Shared form fields never link their description to their input for screen readers (no aria-describedby anywhere in FormField). That gap predates this PR and is not specific to it.
  • The docs still say "you become an owner whatever you pick". That is true for everyone except master admins, and the form now tells master admins the truth.

Tests I added or changed.

  • Common/Tests/App/Dashboard/OwnersOnCreateRules.test.ts: getOwnersNewFromRule (picked people and teams, the creator, any id shape and case, nobody new, the rule left unchanged), and the master admin case (isCreatorMadeOwner, the field line, the nobody-picked text).
  • Common/Tests/App/Dashboard/OwnersOnCreateForm.test.tsx: a rule's line names only new owners, says so when everyone is already an owner, and leaves the creator out. Also the master admin's summary and field line, and the list's accessible name.
  • Common/Tests/Server/Services/RuleRun/IncidentAlertMaintenanceRuleEnginesRun.test.ts: the feed note's whole sentence, for incidents and alerts.
  • E2E/OwnersOnCreate (offline browser suite, CI group 5): 27 tests in about 59 s, up from 22 in about 46 s, so roughly 13 s added. New tests cover a rule whose owners are all picked, Platform no longer repeated, a master admin, and Create Incident Episode (folded Owners, Your teams, the summary's rule, the preview route, the owners the create sends). They also cover Create Alert Episode (Owners on On-Call & Owners) and a rule's own page listing its Creator's Team. The fixture now serves both episode forms and the rule page route, and takes ?admin=1 and ?teams=lots.

What I ran. Offline browser suite 27/27. Common: the 17 suites that read the changed files (847 tests), npx jest Guard (162 suites), npx jest Locale (38 suites), npm run compile, npm run compile-tests. App: npm run compile, the root tests, DashboardLocalesGuard, ProjectScopedApiTenantHeader, the description guards and npx jest Locale (30 suites in all). E2E npm run compile. i18n:extract (nothing new), i18n:check, i18n:validate, the regex timing checker (nothing new), and prettier and eslint on every changed file. The three Common suites I changed also ran with ee/ hidden. Master had not moved since the builder's last merge, so no new merge was needed.

🤖 Generated with Claude Code

valeriamustafaeva and others added 15 commits October 23, 2026 09:34
… add the creator's team

The incident, alert and episode owner rule engines now evaluate in two
halves: a plan (which rules match and who each brings, OwnerRulePlan) and
the writes that carry it out. The plan is what POST
/<event>/owner-rule-preview answers for an event that does not exist yet,
so a create form can say which owner rules will run and whom they add -
worked out by the code the create runs, never guessed in the browser.

Incident and alert owner rules can list teams under Creator's Team
(creatorTeams): of those teams, the ones the person who created the event
is in become owners. A list rather than "every team of the creator",
because people are invited into Members by default.

The Create Alert Episode form's Owners were never added (the service
ignored them); both episode services now ask about owners picked on a
create form before it is saved and add them once it exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…owner rules said on the review, Creator's Team on owner rules

The create forms of incidents, alerts and both episode kinds get an Owners
field (under More fields on incidents, alerts and incident episodes; on
the On-Call & Owners step of alert episodes) with the creator's own teams
one click away under it (Your teams: + Platform). The review step always
lists the owners, with each owner rule that will run and whom it adds,
asked from the server (POST /<event>/owner-rule-preview). Declaring from a
template now starts the field with the template's owners instead of
sending them unseen.

Incident and alert owner rules get a folded Creator's Team section on
their Owners step. A footer's setValue on a people picker writes each
kind's form value, as a pick does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…stead of being cut

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Incident and alert owner rule pages take getCreatorTeamOwnerRuleActionFields,
  so the form a page draws is the one its source says (the form scan reads
  both branches of a conditional); scheduled maintenance keeps the
  inheriting form without the creator's team.
- A new incident or alert owner rule that adds nothing is told it may list a
  team in Creator's Teams.
- ResourceRuleForm, ResourceRuleFormsGuard, OwnersFieldGuard,
  LabelAndOwnerRuleServicesRefuseEmptyRules, RuleTablesAddsNothing,
  ExpiredSessionRouteGuards and ProjectScopedApiTenantHeader cover the
  Creator's Team fold and the four owner-rule-preview routes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d the create forms' Owners row

- Creator's Team moves into the Inherit Owners fold, last after the six
  switches: the Owners step keeps five rows (OverloadedFormStepsGuard), and
  the creator is one more related entity owners come from.
- A severity the preview draft names that is not the project's is answered
  in its own words.
- New: OwnerRulePlan, CreatorTeams, InheritedOwners, OwnerRulePreviewBuilder,
  OwnerRulePreviewRoute, OwnerRulePreview type, EpisodeOwnersPickedOnCreate,
  OwnersOnCreateRules and OwnersOnCreateForm suites; engine run suites cover
  the creator's team and previewRules writing nothing.
- Updated for the Owners field under More fields on Declare Incident, Create
  Alert and Create Incident Episode, the template's owners starting it, and
  the picked-owners step of the episode services.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-owner

# Conflicts:
#	packages/App/FeatureSet/Dashboard/src/Locales/da.json
#	packages/App/FeatureSet/Dashboard/src/Locales/de.json
#	packages/App/FeatureSet/Dashboard/src/Locales/en.json
#	packages/App/FeatureSet/Dashboard/src/Locales/es.json
#	packages/App/FeatureSet/Dashboard/src/Locales/fa.json
#	packages/App/FeatureSet/Dashboard/src/Locales/fr.json
#	packages/App/FeatureSet/Dashboard/src/Locales/hi.json
#	packages/App/FeatureSet/Dashboard/src/Locales/it.json
#	packages/App/FeatureSet/Dashboard/src/Locales/ja.json
#	packages/App/FeatureSet/Dashboard/src/Locales/ko.json
#	packages/App/FeatureSet/Dashboard/src/Locales/nl.json
#	packages/App/FeatureSet/Dashboard/src/Locales/no.json
#	packages/App/FeatureSet/Dashboard/src/Locales/pt.json
#	packages/App/FeatureSet/Dashboard/src/Locales/ru.json
#	packages/App/FeatureSet/Dashboard/src/Locales/sv.json
#	packages/App/FeatureSet/Dashboard/src/Locales/zh-CN.json
#	packages/App/FeatureSet/Dashboard/src/Locales/zh-TW.json
…romium

The real create pages over an in-memory project whose owner rule preview
answers as the server would: Owners folded under More fields, the
declarer's teams one click away and Add all, the review's owner rules (a
label bringing one in), what the preview is asked and what a create sends,
the slow, failed, empty and not-allowed previews, at 1280 and 390 pixels,
dark and German. Runs in Dashboard Offline UI group 5 (about 35 seconds
locally with its bundle).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…orms, in every docs language

- Declaring an Incident: Owners under More fields with your teams one click
  away, the summary's Owners row and the owner rules it lists (Who will own
  it), owners and the owner rule preview through the API, and what a
  Creator's Team adds when owner rules run.
- Alerts Overview and Alert Episodes: the same on Create Alert and Create
  Episode.
- Label and Owner Rules: The creator's team, and the answer to an incident or
  alert owner rule that adds nothing, quoted word for word.
- Docs tests read the shared Owners field of Declare Incident and the new
  server message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ests type-checks

@jest/globals types spyOn and fn as mocks the global jest.SpyInstance,
jest.SpiedFunction and jest.Mock annotations do not accept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-owner

AddOwnerRuleCreatorTeams is renumbered 1806300000000, after master's
AddLabelNameSortKey1806200000000.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ers names the creator's team

Creator's Team waits last in the Inherit Owners fold, and folded, the
fold's line was the only thing a rule's author read: it now says the fold
assigns owners from related entities, or the creator's team. In every
Dashboard language.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…owner rules pages

The owners-on-create fixture renders the real owner rules pages too
(?form=incident-rules|alert-rules): Creator's Team last in the folded
Inherit Owners, whose line names it; one team is enough to save a rule,
named after it and sent as creatorTeams; Edit reads the teams back; only
the rule that adds nothing is marked so; the alert rule's words; and the
field at 390 pixels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…are Incident's Owners and the Creator's Team

Incidents' owners page now counts five routes onto the owners list - the
person who declares, and Owners under More fields on Declare Incident, is
the new first - and its rule form says Creator's Team ends Inherit Owners
and is enough for a new rule. The incident and alert settings pages say
the same of an incident or alert owner rule. In every docs language, with
the new links' anchors localized.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-owner

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@simlarsen

simlarsen commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor Author

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

valeriamustafaeva and others added 2 commits October 23, 2026 13:41
…not an owner yet; a master admin is not told they become one

UI review of the Owners field and the review's Owners row:

- A rule's line on the summary left the owners picked in the field (and the
  person creating an incident or alert) in, so Platform read twice when it was
  picked and a rule also brought it. Each line now names only whom the rule
  adds that is not an owner already, and says 'Everyone it adds is already an
  owner.' when that is nobody (getOwnersNewFromRule).
- OneUptime never makes a master admin the owner of what they create
  (DatabaseService.autoOwnerOnCreate), yet the field told them 'You become an
  owner when you declare it.' A master admin now reads 'Add your team, or
  anyone else who should own it.', and the review says 'Nobody picked.'.
- The rule name column on the review is wide enough for 'Add the creator's
  team as an owner' on one line.
- The owner rules pages' help says the creator's team in plainer words.
- FormSummary keys its steps (React warned on every stepped summary).
- Two new Dashboard strings, translated in all 17 locales.
- Tests: unit and component tests for the new line, the creator left out,
  the master admin; the offline browser suite now covers Create Incident
  Episode, Create Alert Episode, a master admin, a rule whose owners are all
  picked and a rule's own page (27 tests).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts heading; the feed says whose teams were added

- The review's 'Added by owner rules' list is labelled by its heading, so a
  screen reader announces what the list is.
- The incident and alert feed note for the creator's team now reads '... is
  a member of them.' instead of ending on 'is a member.'

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@simlarsen
simlarsen merged commit a7c613b into master Oct 23, 2026
2 of 66 checks passed
@simlarsen
simlarsen deleted the claude/creator-team-owner branch October 23, 2026 13:57
@simlarsen simlarsen mentioned this pull request Oct 23, 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.

1 participant