Skip to content

[One Workflow] fail Scout approval tests on stale approved step/trigger rows#260939

Open
skynetigor wants to merge 2 commits intoelastic:mainfrom
skynetigor:add_check_for_stale_approved_steps
Open

[One Workflow] fail Scout approval tests on stale approved step/trigger rows#260939
skynetigor wants to merge 2 commits intoelastic:mainfrom
skynetigor:add_check_for_stale_approved_steps

Conversation

@skynetigor
Copy link
Copy Markdown
Contributor

Summary

Scout approval specs already required every registered step/trigger (from the internal API) to appear in approved_{step,trigger}_definitions.ts with a matching hash. They did not require the reverse: rows left in those fixtures after a definition was removed from the server still passed.

This change adds a second validation pass so every fixture row must still exist on the server with the same handlerHash / schemaHash, and documents both directions with short comments (Registered ⊆ approved vs Approved ⊆ registered).

Changes

  • step_definitions_approval.spec.ts — After the existing loop over response.body.steps, iterate APPROVED_STEP_DEFINITIONS and assert each id is returned by the API and the hash matches; clear failure messages for stale or mismatched entries. Comment above the original loop explains the forward check.
  • trigger_definitions_approval.spec.ts — Same pattern for APPROVED_TRIGGER_DEFINITIONS and schemaHash.

- Added validation to ensure that every step returned by the server is listed in the fixture with a matching handler hash, catching new or changed handlers not yet approved.
- Implemented checks to confirm that every fixture row still exists on the server with the same hash, addressing stale entries after steps or triggers are removed or lists are not updated.
- Updated comments for clarity on the purpose of the new validations in both step and trigger approval tests.
@skynetigor skynetigor requested a review from Copilot April 2, 2026 13:57
@skynetigor skynetigor added release_note:skip Skip the PR/issue when compiling release notes backport:skip This PR does not require backporting labels Apr 2, 2026
@skynetigor skynetigor marked this pull request as ready for review April 2, 2026 13:58
@skynetigor skynetigor requested a review from a team as a code owner April 2, 2026 13:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds bidirectional validation to Scout approval specs so fixture rows must correspond exactly to currently registered step/trigger definitions (detecting stale approved entries as well as unapproved server changes).

Changes:

  • Add “Approved ⊆ registered” validation pass for triggers to fail on stale/mismatched fixture entries.
  • Add “Approved ⊆ registered” validation pass for steps to fail on stale/mismatched fixture entries.
  • Document the two directions (“Registered ⊆ approved” and “Approved ⊆ registered”) with targeted comments.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
src/platform/plugins/shared/workflows_extensions/test/scout/api/tests/trigger_definitions_approval.spec.ts Adds reverse inclusion checks to detect stale approved trigger fixture rows.
src/platform/plugins/shared/workflows_extensions/test/scout/api/tests/step_definitions_approval.spec.ts Adds reverse inclusion checks to detect stale approved step fixture rows.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 53 to 63
@@ -59,6 +61,22 @@ apiTest.describe(
message: `Trigger "${trigger.id}" has an invalid schema hash`,
}).toBe(trigger.schemaHash);
}
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

Both directions currently do linear .find(...) inside loops, which makes the test O(n²) over the number of triggers. Consider building a Map/object index once for response.body.triggers (and optionally for APPROVED_TRIGGER_DEFINITIONS) and doing constant-time lookups; this improves runtime and avoids duplicating lookup logic in two loops.

Copilot uses AI. Check for mistakes.
Comment on lines +67 to +70
for (const approved of APPROVED_TRIGGER_DEFINITIONS) {
const registeredTrigger = response.body.triggers.find(
(trigger: { id: string; schemaHash: string }) => trigger.id === approved.id
);
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

Both directions currently do linear .find(...) inside loops, which makes the test O(n²) over the number of triggers. Consider building a Map/object index once for response.body.triggers (and optionally for APPROVED_TRIGGER_DEFINITIONS) and doing constant-time lookups; this improves runtime and avoids duplicating lookup logic in two loops.

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +78
expect(registeredTrigger, {
message: `Approved list contains stale entry "${approved.id}" that is not registered`,
}).toBeDefined();

expect(registeredTrigger?.schemaHash, {
message: `Approved entry "${approved.id}" has an invalid schema hash (does not match registered trigger)`,
}).toBe(approved.schemaHash);
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

After asserting registeredTrigger is defined, the follow-up assertion still uses optional chaining (registeredTrigger?.schemaHash). This can make failures harder to interpret and weakens type safety. Prefer asserting defined and then accessing the value directly (e.g., via non-null assertion or by restructuring so the second expect only runs when defined).

Copilot uses AI. Check for mistakes.
Comment on lines 51 to 61
@@ -57,6 +59,22 @@ apiTest.describe(
message: `Step "${step.id}" has an invalid handler hash`,
}).toBe(approvedStep?.handlerHash);
}
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

As with triggers, the two loops do repeated .find(...) lookups, leading to O(n²) behavior. Consider indexing response.body.steps (and/or APPROVED_STEP_DEFINITIONS) into a Map once to make both the forward and reverse checks O(n) and reduce duplicated lookup logic.

Copilot uses AI. Check for mistakes.
Comment on lines +65 to +68
for (const approved of APPROVED_STEP_DEFINITIONS) {
const registeredStep = response.body.steps.find(
(step: { id: string; handlerHash: string }) => step.id === approved.id
);
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

As with triggers, the two loops do repeated .find(...) lookups, leading to O(n²) behavior. Consider indexing response.body.steps (and/or APPROVED_STEP_DEFINITIONS) into a Map once to make both the forward and reverse checks O(n) and reduce duplicated lookup logic.

Copilot uses AI. Check for mistakes.
message: `Approved list contains stale entry "${approved.id}" that is not registered`,
}).toBeDefined();

expect(registeredStep?.handlerHash, {
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

Similar to the trigger spec, optional chaining in the second assertion (registeredStep?.handlerHash) is unnecessary after asserting registeredStep is defined and can obscure intent/type safety. Prefer direct access after the defined-assertion (e.g., using non-null assertion or control flow that guarantees presence).

Suggested change
expect(registeredStep?.handlerHash, {
expect(registeredStep!.handlerHash, {

Copilot uses AI. Check for mistakes.
@botelastic botelastic bot added the Team:One Workflow Team label for One Workflow (Workflow automation) label Apr 2, 2026
@elasticmachine
Copy link
Copy Markdown
Contributor

elasticmachine commented Apr 2, 2026

💔 Build Failed

Failed CI Steps

Test Failures

  • [job] [logs] affected Scout: [ platform / workflows_extensions ] plugin / local-serverless-observability_complete - Workflows Extensions - Custom Step Definitions Approval - should validate that all registered custom step definitions are approved by workflows-eng team
  • [job] [logs] affected Scout: [ platform / workflows_extensions ] plugin / local-serverless-observability_complete - Workflows Extensions - Custom Step Definitions Approval - should validate that all registered custom step definitions are approved by workflows-eng team
  • [job] [logs] affected Scout: [ platform / workflows_extensions ] plugin / local-serverless-search - Workflows Extensions - Custom Step Definitions Approval - should validate that all registered custom step definitions are approved by workflows-eng team
  • [job] [logs] affected Scout: [ platform / workflows_extensions ] plugin / local-serverless-search - Workflows Extensions - Custom Step Definitions Approval - should validate that all registered custom step definitions are approved by workflows-eng team
  • [job] [logs] Scout: [ platform / navigation ] plugin / local-serverless-security_complete - navigation - opens panel on legacy management landing page
  • [job] [logs] affected Scout: [ platform / workflows_extensions ] plugin / local-serverless-security_complete - Workflows Extensions - Custom Step Definitions Approval - should validate that all registered custom step definitions are approved by workflows-eng team
  • [job] [logs] affected Scout: [ platform / workflows_extensions ] plugin / local-serverless-security_complete - Workflows Extensions - Custom Step Definitions Approval - should validate that all registered custom step definitions are approved by workflows-eng team
  • [job] [logs] affected Scout: [ platform / workflows_extensions ] plugin / local-stateful-classic - Workflows Extensions - Custom Step Definitions Approval - should validate that all registered custom step definitions are approved by workflows-eng team
  • [job] [logs] affected Scout: [ platform / workflows_extensions ] plugin / local-stateful-classic - Workflows Extensions - Custom Step Definitions Approval - should validate that all registered custom step definitions are approved by workflows-eng team

Metrics [docs]

✅ unchanged

History

Copy link
Copy Markdown
Contributor

@yngrdyn yngrdyn left a comment

Choose a reason for hiding this comment

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

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting release_note:skip Skip the PR/issue when compiling release notes Team:One Workflow Team label for One Workflow (Workflow automation)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants