Skip to content

TRT-2364: Fix timestamp and date type inconsistencies - #3716

Merged
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
mstaeble:trt-2364-timestamp-consistency
Aug 20, 2026
Merged

TRT-2364: Fix timestamp and date type inconsistencies#3716
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
mstaeble:trt-2364-timestamp-consistency

Conversation

@mstaeble

@mstaeble mstaeble commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replace epoch millisecond integers with proper TIMESTAMP WITH TIME ZONE and DATE types across the database schema, API layer, and frontend
  • Enforce UTC timezone on all PostgreSQL connections
  • Use civil.Date for date-only fields (GA dates, development start dates, CountByDate, CalendarEvent)
  • Change CalendarEvent.Start/End from string to time.Time
  • Change ChatConversationResponse.CreatedAt from string to time.Time
  • Change JobRun.Timestamp from int to time.Time (RFC 3339 in JSON)
  • Use ISO 8601 strings for timestamp filter values (frontend and backend)
  • Remove epoch extraction from SQL filters; compare timestamptz directly
  • Fix pre-existing bug: /api/jobs failed when timestamp filters were present (added filter.StripJobRunFilters)
  • Rewrite JobsDetail day bucketing with Temporal.PlainDate
  • Add timestamp/date type guidelines to project instructions
  • Update API docs to show RFC 3339 and YYYY-MM-DD formats

Note: Production databases should also have their default timezone set to UTC via ALTER DATABASE <name> SET timezone = 'UTC'.

Depends on (will need conflict resolution):

Test plan

  • make lint passes
  • make test passes (Go + JS + MCP)
  • make verify-apm passes
  • Independent code review (isolated sub-agent, two rounds)

Manual verification against staging-2 (prod database clone)

Ran sippy migrate and sippy refresh against a clone of the production database, then served locally with --data-provider postgres.

API responses verified:

  • /api/jobs/runs - timestamp is RFC 3339 string (was epoch ms integer)
  • /api/releases - ga_dates are YYYY-MM-DD, dates.ga are YYYY-MM-DD, last_updated is RFC 3339
  • /api/jobs/details - start/end are YYYY-MM-DD (civil.Date), JobRunResult.timestamp is RFC 3339
  • /api/tests/analysis/overall - CountByDate.date is YYYY-MM-DD (civil.Date)
  • /api/releases/tags/events - CalendarEvent.start is RFC 3339
  • /api/incidents - CalendarEvent.start/end are RFC 3339

UI pages verified:

  • Job runs table renders timestamps correctly, sorting and filtering work
  • Job analysis day/hour toggle works (found and fixed pre-existing StripJobRunFilters bug)
  • Build cluster details page loads with timestamp filter
  • Release payloads calendar renders tags on correct dates
  • Component Readiness - skipped (pre-existing Suite variant error with postgres data provider, unrelated to this PR)
  • JobsDetail day bucketing - skipped (dead code since April 2022, no UI route)
  • E2E tests

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • API timestamps now use ISO 8601/RFC 3339 values, while date-only fields use YYYY-MM-DD.
    • Timestamp and date filters support ISO-formatted values across tables, charts, and reports.
    • Data grids provide improved date sorting, relative-time labels, tooltips, and empty-value handling.
    • Job detail reports organize results by calendar day across a 14-day range.
  • Bug Fixes

    • Improved UTC consistency and accuracy across reports, filters, release data, and disruption views.
  • Documentation

    • Added guidance for date and timestamp formats and frontend date handling.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: automatic mode

@openshift-ci-robot

openshift-ci-robot commented Jun 29, 2026

Copy link
Copy Markdown

@mstaeble: This pull request references TRT-2364 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Replace epoch millisecond integers with proper TIMESTAMP WITH TIME ZONE and DATE types across the database schema, API layer, and frontend
  • Enforce UTC timezone on all PostgreSQL connections
  • Use civil.Date for date-only fields (GA dates, development start dates)
  • Change JobRun.Timestamp from int to time.Time (RFC 3339 in JSON)
  • Use ISO 8601 strings for timestamp filter values (frontend and backend)
  • Rewrite JobsDetail day bucketing with Temporal.PlainDate
  • Add timestamp/date type guidelines to project instructions

Note: Production databases should also have their default timezone set to UTC via ALTER DATABASE <name> SET timezone = 'UTC'.

Depends on (will need conflict resolution):

Test plan

  • make lint passes
  • make test passes (Go + JS + MCP)
  • make verify-apm passes
  • Manual verification: job runs table renders timestamps correctly
  • Manual verification: timestamp filter date picker works
  • Manual verification: Component Readiness GA date handling works
  • E2E tests pass

🤖 Generated with Claude Code

@coderabbitai ignore

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jun 29, 2026
@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 29, 2026
@openshift-ci

openshift-ci Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@openshift-ci-robot Thanks for the heads-up. This looks like a Jira metadata warning rather than a code review issue on the PR itself.

The actionable item here is for the linked story TRT-2364 to have its target version set to 5.0.0 for this branch. Once that Jira field is updated, this warning should clear.

@mstaeble
mstaeble force-pushed the trt-2364-timestamp-consistency branch 2 times, most recently from bb354da to 0ce2e75 Compare June 30, 2026 03:33
@mstaeble

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@mstaeble, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 52 minutes

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 0a395404-50a8-4e96-b653-feab8d650604

📥 Commits

Reviewing files that changed from the base of the PR and between 9ba64f3 and 1f41be4.

📒 Files selected for processing (16)
  • cmd/sippy/seed_data.go
  • pkg/api/componentreadiness/dataprovider/postgres/provider.go
  • pkg/api/job_runs.go
  • pkg/api/jobs.go
  • pkg/api/releases.go
  • pkg/api/tests.go
  • pkg/db/functions.go
  • pkg/db/query/test_queries.go
  • pkg/flags/postgres_benchmarking_test.go
  • pkg/sippyserver/server.go
  • sippy-ng/src/build_clusters/BuildClusterDetails.jsx
  • sippy-ng/src/jobs/JobRunsTable.jsx
  • sippy-ng/src/jobs/JobTable.jsx
  • test/integration/component_readiness_test.go
  • test/integration/job_runs_report_test.go
  • test/integration/jobs_test.go

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: c5d5d016-006f-4192-b437-524087c6d5d6

📥 Commits

Reviewing files that changed from the base of the PR and between c192dbd and 9ba64f3.

📒 Files selected for processing (6)
  • cmd/sippy/main.go
  • cmd/sippy/seed_data.go
  • pkg/api/README.md
  • pkg/api/tests.go
  • pkg/apis/api/types.go
  • pkg/sippyserver/server.go
🚧 Files skipped from review as they are similar to previous changes (5)
  • pkg/sippyserver/server.go
  • cmd/sippy/main.go
  • pkg/api/README.md
  • pkg/api/tests.go
  • cmd/sippy/seed_data.go

Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review.


Walkthrough

The PR standardizes temporal data handling across Go APIs, database queries, frontend grids, filters, release dates, and job reports. Epoch values and timezone-ambiguous dates now use typed UTC timestamps, ISO strings, civil.Date, and Temporal.PlainDate.

Changes

Temporal data standardization

Layer / File(s) Summary
Temporal contracts and storage
pkg/apis/..., pkg/filter/filterable.go, pkg/db/...
Public types, database functions, filtering, sorting, and storage distinguish timestamps from date-only values.
Release dates and API query flow
pkg/api/..., pkg/dataloader/..., pkg/sippyserver/..., cmd/sippy/...
Release dates use civil.Date; API and query paths use typed timestamps, UTC values, and half-open date ranges.
Frontend temporal handling
sippy-ng/src/...
DataGrid columns return Date objects, filters store ISO values, and job details use Temporal.PlainDate for calendar-day calculations.
Validation and guidance
test/integration/..., pkg/api/README.md, .apm/instructions/*, apm.lock.yaml
Tests, examples, instructions, and rule hashes reflect the updated temporal formats.

Estimated code review effort: 4 (Complex) | ~60 minutes

Merge Risk: ⚪ Minimal · up to 9ba64

The timestamp and date consistency changes are merge-ready after normal checks and review; no actionable merge-blocking risk remains.

Possibly related PRs

  • openshift/sippy#3907: Both changes modify JobDetailsReport and its release-scoped query behavior in pkg/api/jobs.go.

Suggested reviewers: smg247, deepsm007

🚥 Pre-merge checks | ✅ 18 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Go Error Handling ⚠️ Warning The PR adds unwrapped GetTimestampValue errors in filterTimestamp and logs then ignores timestamp getter errors in Compare, sorting with zero values. Wrap the getter error with fmt.Errorf("...: %w", err), and propagate or explicitly handle Compare errors instead of continuing after log.Error.
Test Coverage For New Features ⚠️ Warning New pure Go timestamp filtering and GetTimestampValue methods have no tests; the Temporal.PlainDate JobsDetail rewrite has no frontend test, and the /api/jobs filter fix lacks a regression test. Add unit tests for timestamp filtering, sorting, BQ parameters, and GetTimestampValue methods; add a /api/jobs timestamp-filter regression test and JobsDetail/date-filter frontend tests.
✅ Passed checks (18 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the primary changes to timestamp and date handling across the codebase.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Sql Injection Prevention ✅ Passed The diff uses placeholders for request values in Jira and job queries; BigQuery filters bind named parameters. Remaining formatted identifiers are fixed names, and no changed code introduces user-i...
Excessive Css In React Should Use Styles ✅ Passed The JSX diff adds no inline style or sx declarations. Existing inline objects, including the four-property JobRunsTable block, are unchanged from HEAD^.
Single Responsibility And Clear Naming ✅ Passed The diff adds focused names such as GetTimestampValue, filterTimestamp, and CivilDatePtr; changed structs retain their field counts, and no new broad package or type is introduced.
Feature Documentation ✅ Passed The PR updates API documentation and project instructions; docs/features contains only an unrelated symptoms document. Feature-doc updates are encouraged but explicitly not required.
Stable And Deterministic Test Names ✅ Passed The pull-request diff adds or updates standard Go tests only; repository searches found no first-party Ginkgo imports or It/Describe/Context/When declarations.
Test Structure And Quality ✅ Passed PASS: The changed test files use standard testing.T and testify; repository source has no Ginkgo/Gomega test constructs, cluster waits, or Ginkgo It blocks for this check to assess.
Microshift Test Compatibility ✅ Passed The HEAD diff adds no Ginkgo tests: all 14 changed Go test files use standard testing, and searches found no Ginkgo imports or Describe/Context/When/It declarations.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The PR adds no Ginkgo e2e tests or It/Describe/Context/When declarations; changed tests are standard Go unit/integration tests and make no SNO-relevant cluster assumptions.
Topology-Aware Scheduling Compatibility ✅ Passed The PR changes Go/JS code, documentation, and a lock file only; the diff adds no deployment manifests, operators, controllers, or scheduling constraints.
Ote Binary Stdout Contract ✅ Passed The diff adds only UTC timezone initialization in cmd/sippy init and TestMain; it adds no stdout writes, OTE suite hooks, or OTE binary communication code.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The PR changes no test/e2e files and adds no Ginkgo declarations; added lines contain no IPv4-only assumptions or external connectivity requirements.
No-Weak-Crypto ✅ Passed The PR diff adds no MD5, SHA-1, DES, RC4, Blowfish, ECB, custom crypto, or secret comparison; existing MD5 checksum code is unchanged, and added hashing is pre-existing SHA-256.
Container-Privileges ✅ Passed The PR changes no container or Kubernetes manifest and adds no prohibited security setting; existing chat build-time USER root is unchanged and runtime uses non-root sippy.
No-Sensitive-Data-In-Logs ✅ Passed The diff adds no logging of passwords, tokens, API keys, PII, hostnames, or customer data; new logs contain only timestamp filter input, field names, dates, counts, and errors.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
sippy-ng/src/component_readiness/TriagedRegressionTestList.js (1)

215-235: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Set type: 'date' on the Last Failure column.

The valueGetter now returns a Date object, but the column lacks type: 'date', so DataGrid sorting/filtering will not treat it as a date.

♻️ Proposed change
     {
       field: 'last_failure',
       headerName: 'Last Failure',
       flex: 12,
       filterable: false,
+      type: 'date',
       valueGetter: (params) => {

As per coding guidelines: "For MUI DataGrid timestamp columns, use type: 'date' with a valueGetter that returns a Date object."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sippy-ng/src/component_readiness/TriagedRegressionTestList.js` around lines
215 - 235, The Last Failure column in TriagedRegressionTestList is returning a
Date from its valueGetter but is missing the DataGrid date type. Update the
column definition for the last_failure field to include type: 'date' so MUI
DataGrid sorts and filters it as a date; keep the existing valueGetter and
renderCell behavior unchanged.

Source: Coding guidelines

sippy-ng/src/component_readiness/RegressedTestsPanel.js (1)

215-265: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Set type: 'date' on these timestamp columns.

Both Regressed Since and Last Failure now return Date objects from valueGetter, but neither column declares type: 'date'. Per the frontend guideline, MUI DataGrid timestamp columns should use type: 'date' with a valueGetter returning a Date so sorting and any date filtering behave correctly.

♻️ Proposed change
     {
       field: 'regression',
       headerName: 'Regressed Since',
       flex: 12,
       filterable: false,
+      type: 'date',
       valueGetter: (params) => {
     {
       field: 'last_failure',
       headerName: 'Last Failure',
       flex: 12,
       filterable: false,
+      type: 'date',
       valueGetter: (params) => {

As per coding guidelines: "For MUI DataGrid timestamp columns, use type: 'date' with a valueGetter that returns a Date object."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sippy-ng/src/component_readiness/RegressedTestsPanel.js` around lines 215 -
265, The RegressedTestsPanel DataGrid columns for Regessed Since and Last
Failure return Date objects from their valueGetter functions but do not declare
the column type, so update both column definitions to use type: 'date' while
keeping the existing valueGetter logic in place. This applies to the column
objects that define field 'regression' and field 'last_failure', so sorting and
date-aware behavior work consistently with the Date values being returned.

Source: Coding guidelines

pkg/api/test_analysis.go (1)

25-43: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Anchor the overall analysis window to reportEnd.

The grouped queries use the caller-provided reportEnd, but the overall query still uses wall-clock time.Now() and has no upper bound. Historical report requests can return an overall series for a different 14-day window than the job or variant series.

Proposed fix
-		Where("date >= ?", time.Now().Add(-24*14*time.Hour)).
+		Where("date <= ?", reportEnd).
+		Where("date >= ?", reportEnd.Add(-24*14*time.Hour)).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/api/test_analysis.go` around lines 25 - 43, The overall query in
GetTestAnalysisOverallFromDB is using wall-clock time instead of the
caller-provided reportEnd, so its date window can drift from the other series.
Update the time filter in GetTestAnalysisOverallFromDB to anchor the 14-day
lookback on reportEnd, and add an upper bound at reportEnd so the overall series
matches the grouped queries’ window; use the existing query builder chain in
GetTestAnalysisOverallFromDB to make the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@sippy-ng/src/datagrid/GridToolbarFilterItem.js`:
- Around line 107-112: The date filter update in GridToolbarFilterItem’s
onChange handler is rebuilding the filter model without carrying over
props.filterModel.not, which causes negated date filters to lose their negation
state after a picker change. Update the props.setFilterModel call in this date
value change path to preserve the existing not flag from props.filterModel
alongside columnField, operatorValue, and value so the filter behavior stays
consistent.

In `@sippy-ng/src/jobs/JobsDetail.js`:
- Around line 57-58: The job details flow in JobsDetail.js uses
Temporal.PlainDate.from directly, but the frontend does not guarantee native
Temporal support. Import the Temporal polyfill in this module (or a shared entry
point used before JobsDetail runs) and ensure the existing
setStartDate/setEndDate logic uses that polyfilled Temporal reference so opening
job details works in browsers without native support.

---

Outside diff comments:
In `@pkg/api/test_analysis.go`:
- Around line 25-43: The overall query in GetTestAnalysisOverallFromDB is using
wall-clock time instead of the caller-provided reportEnd, so its date window can
drift from the other series. Update the time filter in
GetTestAnalysisOverallFromDB to anchor the 14-day lookback on reportEnd, and add
an upper bound at reportEnd so the overall series matches the grouped queries’
window; use the existing query builder chain in GetTestAnalysisOverallFromDB to
make the change.

In `@sippy-ng/src/component_readiness/RegressedTestsPanel.js`:
- Around line 215-265: The RegressedTestsPanel DataGrid columns for Regessed
Since and Last Failure return Date objects from their valueGetter functions but
do not declare the column type, so update both column definitions to use type:
'date' while keeping the existing valueGetter logic in place. This applies to
the column objects that define field 'regression' and field 'last_failure', so
sorting and date-aware behavior work consistently with the Date values being
returned.

In `@sippy-ng/src/component_readiness/TriagedRegressionTestList.js`:
- Around line 215-235: The Last Failure column in TriagedRegressionTestList is
returning a Date from its valueGetter but is missing the DataGrid date type.
Update the column definition for the last_failure field to include type: 'date'
so MUI DataGrid sorts and filters it as a date; keep the existing valueGetter
and renderCell behavior unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 2edbb857-8aaf-4fc5-8ae1-8d17c2410c15

📥 Commits

Reviewing files that changed from the base of the PR and between 82be7b8 and 0ce2e75.

⛔ Files ignored due to path filters (8)
  • .claude/rules/backend.md is excluded by !.claude/**
  • .claude/rules/frontend.md is excluded by !.claude/**
  • .cursor/rules/backend.mdc is excluded by !.cursor/**
  • .cursor/rules/frontend.mdc is excluded by !.cursor/**
  • AGENTS.md is excluded by !AGENTS.md
  • CLAUDE.md is excluded by !CLAUDE.md
  • sippy-ng/AGENTS.md is excluded by !sippy-ng/AGENTS.md
  • sippy-ng/CLAUDE.md is excluded by !sippy-ng/CLAUDE.md
📒 Files selected for processing (35)
  • .apm/instructions/backend.instructions.md
  • .apm/instructions/frontend.instructions.md
  • apm.lock.yaml
  • pkg/api/README.md
  • pkg/api/componentreadiness/dataprovider/bigquery/releasedates.go
  • pkg/api/componentreadiness/dataprovider/postgres/provider.go
  • pkg/api/componentreadiness/queryparamparser_test.go
  • pkg/api/componentreadiness/triage_test.go
  • pkg/api/componentreadiness/utils/utils_test.go
  • pkg/api/job_runs.go
  • pkg/api/jobs.go
  • pkg/api/releases.go
  • pkg/api/releases_test.go
  • pkg/api/test_analysis.go
  • pkg/apis/api/types.go
  • pkg/apis/sippy/v1/types.go
  • pkg/apis/sippyprocessing/v1/types.go
  • pkg/db/db.go
  • pkg/db/views.go
  • pkg/filter/filterable.go
  • pkg/sippyserver/chat_conversations.go
  • pkg/sippyserver/parameters.go
  • pkg/sippyserver/server.go
  • pkg/util/utils.go
  • pkg/util/utils_test.go
  • sippy-ng/src/App.js
  • sippy-ng/src/build_clusters/BuildClusterDetails.js
  • sippy-ng/src/component_readiness/RegressedTestsPanel.js
  • sippy-ng/src/component_readiness/TriagedRegressionTestList.js
  • sippy-ng/src/datagrid/GridToolbarFilterItem.js
  • sippy-ng/src/datagrid/utils.js
  • sippy-ng/src/helpers.js
  • sippy-ng/src/jobs/JobRunsTable.js
  • sippy-ng/src/jobs/JobStackedChart.js
  • sippy-ng/src/jobs/JobsDetail.js
💤 Files with no reviewable changes (1)
  • sippy-ng/src/App.js

Comment thread sippy-ng/src/datagrid/GridToolbarFilterItem.jsx
Comment thread sippy-ng/src/jobs/JobsDetail.jsx
@mstaeble
mstaeble force-pushed the trt-2364-timestamp-consistency branch from 0ce2e75 to 4c44aed Compare June 30, 2026 13:08
@openshift-ci openshift-ci Bot added the ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review label Jun 30, 2026
@mstaeble
mstaeble force-pushed the trt-2364-timestamp-consistency branch from 4c44aed to fddef49 Compare June 30, 2026 13:57
@mstaeble mstaeble changed the title [WIP] TRT-2364: Fix timestamp and date type inconsistencies TRT-2364: Fix timestamp and date type inconsistencies Jun 30, 2026
@mstaeble
mstaeble marked this pull request as ready for review June 30, 2026 14:08
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 30, 2026
@openshift-ci
openshift-ci Bot requested review from deepsm007 and smg247 June 30, 2026 14:09

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
sippy-ng/src/tests/FeatureGates.js (1)

213-225: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Potential in-place mutation of the memoized default.

When the filters param is absent, filterModel is the memoized defaultFilterModel. requestSearch mutates currentFilters.items in place (filterModel.items.filter(...) assigned back), and bookmarks[0].model also points at defaultFilterModel.items (Line 127). Mutating the shared default can corrupt the bookmark/default state. Consider cloning before mutating.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sippy-ng/src/tests/FeatureGates.js` around lines 213 - 225, The requestSearch
helper in FeatureGates is mutating the shared memoized defaultFilterModel
through filterModel/currentFilters, which can corrupt bookmark/default state
because bookmarks[0].model also points at that same items array. Update
requestSearch to work on a cloned filter model and cloned items before
filtering/pushing the feature_gate criterion, then pass the new object to
setFilterModel so defaultFilterModel is never modified in place.
pkg/testidentification/ocp_variants.go (1)

110-114: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Bug: existence check uses the wrong map key, dropping accumulated variant values.

variantKeyValues is keyed by variant name (e.g. AllPlatforms() reads variantValues["Platform"]), and the insert/create branches both key by v.VariantName. Changing the lookup to variantKeyValues[v.VariantValue] means the ok check almost never matches the key actually written. As a result, the else branch runs on every value for a given name and overwrites the set instead of inserting, so only the last value per variant name survives.

The check must use the same key as the writes (v.VariantName):

🐛 Proposed fix
-			if _, ok := variantKeyValues[v.VariantValue]; ok {
+			if _, ok := variantKeyValues[v.VariantName]; ok {
 				variantKeyValues[v.VariantName].Insert(v.VariantValue)
 			} else {
 				variantKeyValues[v.VariantName] = sets.NewString(v.VariantValue)
 			}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/testidentification/ocp_variants.go` around lines 110 - 114, The existence
check in the variant accumulation logic uses the wrong map key, causing
previously collected values to be lost. In the code that updates
variantKeyValues, make sure the lookup matches the same key used for writes,
namely v.VariantName, so the insert branch is taken when that variant name
already exists and values are accumulated instead of overwritten.
🧹 Nitpick comments (3)
sippy-ng/src/App.js (1)

498-502: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Restore the [isLoaded] dependency array.

Dropping the dependency array makes this effect run after every render. The if (!isLoaded) guard prevents repeated fetches, so behavior is effectively unchanged, but running the callback on every render is unnecessary and diverges from the prior intent (run when isLoaded transitions). Re-adding [isLoaded] is clearer and keeps react-hooks/exhaustive-deps happy.

♻️ Suggested change
   useEffect(() => {
     if (!isLoaded) {
       fetchData()
     }
-  })
+  }, [isLoaded])
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sippy-ng/src/App.js` around lines 498 - 502, Restore the missing dependency
array on the useEffect in App.js so the fetch logic only runs when isLoaded
changes, not after every render. Update the effect that calls fetchData to
include [isLoaded], keeping the existing !isLoaded guard intact and preserving
the intended transition-based behavior while satisfying
react-hooks/exhaustive-deps.
sippy-ng/src/tests/TestAnalysis.js (1)

63-72: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Inline default recreates filterModel every render.

When the filters param is absent, this destructure default produces a brand-new object on each render (unlike the prior stable-reference helper). It feeds the dependency array of the page-context effect (Lines 162-170), so setPageContextForChat will rerun on every render. Consider wrapping the default in useMemo keyed on testName.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sippy-ng/src/tests/TestAnalysis.js` around lines 63 - 72, The inline fallback
for `filterModel` in `TestAnalysis` creates a new object on every render when
`filters` is missing, which makes the `useEffect` that calls
`setPageContextForChat` keep retriggering. Move that default construction into a
`useMemo` in `TestAnalysis`, keyed on `testName`, and use the memoized value in
the `useQueryParam('filters', SafeJSONParam)` destructure so the `filterModel`
reference stays stable across renders.
pkg/filter/filterable.go (1)

58-68: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use sets.String for jobRunFields. This is a hand-rolled set; switch to k8s.io/apimachinery/pkg/util/sets and Has() for consistency with the Go guidelines.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/filter/filterable.go` around lines 58 - 68, The `jobRunFields` lookup in
`StripJobRunFilters` is a hand-rolled set and should be converted to
`k8s.io/apimachinery/pkg/util/sets.String` for consistency. Update the
`jobRunFields` declaration to use a `sets.String` value, then change the
membership check inside `StripJobRunFilters` to use `Has()` instead of map
indexing. Keep the rest of the filter-copy logic unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/filter/filterable.go`:
- Line 670: Update Filter.Filter in filterable.go to handle
apitype.ColumnTypeTimestamp in-memory alongside the existing string, numerical,
and array branches, since JobRun.GetFieldType("timestamp") now resolves to a
timestamp type. Add a dedicated timestamp branch that parses the filter value as
RFC3339, compares it against the item's timestamp field, and returns the same
style of match/non-match result as the other field-type handlers. Also add
regression coverage around the Filter.Filter path to verify timestamp filtering
works and no longer falls through to the “unknown field or field type” case.

In `@sippy-ng/src/component_readiness/TriagedRegressionTestList.js`:
- Around line 221-226: The `valueGetter` in `TriagedRegressionTestList` should
guard against `params.row.last_failure` being null or undefined before accessing
`.Valid`. Update the existing `valueGetter` logic to first check that
`last_failure` exists, then return null when it is missing or invalid, and only
construct the `Date` from `params.row.last_failure.Time` when the object is
present and valid.

In `@sippy-ng/src/jobs/JobAnalysis.js`:
- Around line 160-162: The fetch effect in JobAnalysis is missing props.release
in its dependency list, so navigation between releases can reuse stale data.
Update the useEffect that calls fetchData() to depend on props.release as well
as filterModel and period, and ensure fetchData uses the current release value
from props.release when building the request.

In `@sippy-ng/src/jobs/JobRunsTable.js`:
- Around line 165-172: The timestamp handling in JobRunsTable is missing a
null/invalid guard, so `valueGetter` and `renderCell` can produce `Invalid Date`
when `params.value` is absent or bad. Update the column logic in `JobRunsTable`
to match the defensive pattern used in `RegressedTestsPanel`: return `null` from
`valueGetter` when the timestamp is missing/invalid, and short-circuit
`renderCell` so it renders nothing instead of calling `toLocaleString()` or
`relativeTime()` on an invalid date.

In `@sippy-ng/src/jobs/JobTable.js`:
- Around line 549-551: JobTable does not refetch data when props.release
changes, so stale rows can remain in release-scoped views. Update the useEffect
that calls fetchData() in JobTable to include props.release in its dependency
list, ensuring the effect reruns whenever the release context changes. Keep the
fix localized to the fetchData-triggering effect and preserve the existing
period, filterModel, sort, and sortField dependencies.

In `@sippy-ng/src/pull_requests/PullRequestsTable.js`:
- Around line 371-373: The fetch effect in PullRequestsTable is missing
props.release from its dependency list, so release changes can leave stale pull
request data on screen. Update the useEffect that calls fetchData to include
props.release alongside filterModel, sort, sortField, and view so the request
reruns whenever the active release changes, especially when rendered from
RepositoryDetails.

In `@sippy-ng/src/releases/PayloadStreamTestFailures.js`:
- Around line 198-200: The fetch effect is missing the release stream query
inputs it actually depends on, so updates to release, arch, or stream can leave
PayloadStreamTestFailures showing stale results. Update the useEffect in
PayloadStreamTestFailures so its dependency array includes the values read by
fetchData(), alongside the existing filterModel, sort, and sortField
dependencies, ensuring the table refetches whenever those query params change.

In `@sippy-ng/src/releases/ReleasePayloadPullRequests.js`:
- Around line 159-161: The effect in ReleasePayloadPullRequests is missing the
server-side sort dependencies, so changing sort no longer triggers a refetch.
Update the useEffect that calls fetchData to depend on filterModel, sort, and
sortField, matching the other table components and ensuring the query rebuilt by
fetchData stays in sync with sorting changes. Keep the logic in
ReleasePayloadPullRequests aligned with PayloadStreamsTable,
ReleasePayloadTable, and ReleasePayloadJobRuns so server-side sorting continues
to work.

---

Outside diff comments:
In `@pkg/testidentification/ocp_variants.go`:
- Around line 110-114: The existence check in the variant accumulation logic
uses the wrong map key, causing previously collected values to be lost. In the
code that updates variantKeyValues, make sure the lookup matches the same key
used for writes, namely v.VariantName, so the insert branch is taken when that
variant name already exists and values are accumulated instead of overwritten.

In `@sippy-ng/src/tests/FeatureGates.js`:
- Around line 213-225: The requestSearch helper in FeatureGates is mutating the
shared memoized defaultFilterModel through filterModel/currentFilters, which can
corrupt bookmark/default state because bookmarks[0].model also points at that
same items array. Update requestSearch to work on a cloned filter model and
cloned items before filtering/pushing the feature_gate criterion, then pass the
new object to setFilterModel so defaultFilterModel is never modified in place.

---

Nitpick comments:
In `@pkg/filter/filterable.go`:
- Around line 58-68: The `jobRunFields` lookup in `StripJobRunFilters` is a
hand-rolled set and should be converted to
`k8s.io/apimachinery/pkg/util/sets.String` for consistency. Update the
`jobRunFields` declaration to use a `sets.String` value, then change the
membership check inside `StripJobRunFilters` to use `Has()` instead of map
indexing. Keep the rest of the filter-copy logic unchanged.

In `@sippy-ng/src/App.js`:
- Around line 498-502: Restore the missing dependency array on the useEffect in
App.js so the fetch logic only runs when isLoaded changes, not after every
render. Update the effect that calls fetchData to include [isLoaded], keeping
the existing !isLoaded guard intact and preserving the intended transition-based
behavior while satisfying react-hooks/exhaustive-deps.

In `@sippy-ng/src/tests/TestAnalysis.js`:
- Around line 63-72: The inline fallback for `filterModel` in `TestAnalysis`
creates a new object on every render when `filters` is missing, which makes the
`useEffect` that calls `setPageContextForChat` keep retriggering. Move that
default construction into a `useMemo` in `TestAnalysis`, keyed on `testName`,
and use the memoized value in the `useQueryParam('filters', SafeJSONParam)`
destructure so the `filterModel` reference stays stable across renders.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: d990cb2f-d180-42be-82df-c4e55ba8c139

📥 Commits

Reviewing files that changed from the base of the PR and between d32d1f8 and fddef49.

⛔ Files ignored due to path filters (8)
  • .claude/rules/backend.md is excluded by !.claude/**
  • .claude/rules/frontend.md is excluded by !.claude/**
  • .cursor/rules/backend.mdc is excluded by !.cursor/**
  • .cursor/rules/frontend.mdc is excluded by !.cursor/**
  • AGENTS.md is excluded by !AGENTS.md
  • CLAUDE.md is excluded by !CLAUDE.md
  • sippy-ng/AGENTS.md is excluded by !sippy-ng/AGENTS.md
  • sippy-ng/CLAUDE.md is excluded by !sippy-ng/CLAUDE.md
📒 Files selected for processing (51)
  • .apm/instructions/backend.instructions.md
  • .apm/instructions/frontend.instructions.md
  • apm.lock.yaml
  • config/openshift.yaml
  • pkg/api/README.md
  • pkg/api/componentreadiness/dataprovider/bigquery/releasedates.go
  • pkg/api/componentreadiness/dataprovider/postgres/provider.go
  • pkg/api/componentreadiness/queryparamparser_test.go
  • pkg/api/componentreadiness/triage_test.go
  • pkg/api/componentreadiness/utils/utils_test.go
  • pkg/api/job_runs.go
  • pkg/api/jobs.go
  • pkg/api/releases.go
  • pkg/api/releases_test.go
  • pkg/api/test_analysis.go
  • pkg/apis/api/types.go
  • pkg/apis/sippy/v1/types.go
  • pkg/apis/sippyprocessing/v1/types.go
  • pkg/db/db.go
  • pkg/db/views.go
  • pkg/filter/filterable.go
  • pkg/sippyserver/chat_conversations.go
  • pkg/sippyserver/parameters.go
  • pkg/sippyserver/server.go
  • pkg/testidentification/ocp_variants.go
  • pkg/util/utils.go
  • pkg/util/utils_test.go
  • pkg/variantregistry/snapshot.yaml
  • sippy-ng/src/App.js
  • sippy-ng/src/build_clusters/BuildClusterDetails.js
  • sippy-ng/src/component_readiness/RegressedTestsPanel.js
  • sippy-ng/src/component_readiness/TriagedRegressionTestList.js
  • sippy-ng/src/datagrid/GridToolbarFilterItem.js
  • sippy-ng/src/datagrid/utils.js
  • sippy-ng/src/helpers.js
  • sippy-ng/src/jobs/JobAnalysis.js
  • sippy-ng/src/jobs/JobRunsTable.js
  • sippy-ng/src/jobs/JobStackedChart.js
  • sippy-ng/src/jobs/JobTable.js
  • sippy-ng/src/jobs/JobsDetail.js
  • sippy-ng/src/pull_requests/PullRequestsTable.js
  • sippy-ng/src/releases/PayloadStreamTestFailures.js
  • sippy-ng/src/releases/PayloadStreamsTable.js
  • sippy-ng/src/releases/PayloadTestFailures.js
  • sippy-ng/src/releases/ReleasePayloadJobRuns.js
  • sippy-ng/src/releases/ReleasePayloadPullRequests.js
  • sippy-ng/src/releases/ReleasePayloadTable.js
  • sippy-ng/src/repositories/RepositoriesTable.js
  • sippy-ng/src/tests/FeatureGates.js
  • sippy-ng/src/tests/TestAnalysis.js
  • sippy-ng/src/tests/TestTable.js

Comment thread pkg/filter/filterable.go Outdated
Comment thread sippy-ng/src/component_readiness/TriagedRegressionTestList.jsx
Comment thread sippy-ng/src/jobs/JobAnalysis.js Outdated
Comment thread sippy-ng/src/jobs/JobRunsTable.jsx
Comment thread sippy-ng/src/jobs/JobTable.js Outdated
Comment thread sippy-ng/src/pull_requests/PullRequestsTable.js Outdated
Comment thread sippy-ng/src/releases/PayloadStreamTestFailures.js Outdated
Comment thread sippy-ng/src/releases/ReleasePayloadPullRequests.js Outdated
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e

@mstaeble
mstaeble force-pushed the trt-2364-timestamp-consistency branch from fddef49 to 2937c21 Compare June 30, 2026 16:47

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/variantregistry/snapshot.yaml`:
- Around line 26693-26695: The perfscale `multi-ns` jobs are being recorded with
`Architecture: multi`, which causes x86-only jobs to be treated as multi-arch in
downstream variant consumers. Update the snapshot generation in
`pkg/variantregistry/snapshot.go` so these `*-x86-*` entries keep `Architecture`
as `amd64`, and move the `multi-ns` distinction into a separate variant field or
the job key instead. Then regenerate the affected `snapshot.yaml` entries for
the
`periodic-ci-openshift-eng-ocp-qe-perfscale-ci-main-aws-4.22-nightly-x86-cudn-density-multi-ns-500-24nodes`
family.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 634f7723-be81-4a5e-b5b0-3b1a6059594c

📥 Commits

Reviewing files that changed from the base of the PR and between fddef49 and 2937c21.

⛔ Files ignored due to path filters (8)
  • .claude/rules/backend.md is excluded by !.claude/**
  • .claude/rules/frontend.md is excluded by !.claude/**
  • .cursor/rules/backend.mdc is excluded by !.cursor/**
  • .cursor/rules/frontend.mdc is excluded by !.cursor/**
  • AGENTS.md is excluded by !AGENTS.md
  • CLAUDE.md is excluded by !CLAUDE.md
  • sippy-ng/AGENTS.md is excluded by !sippy-ng/AGENTS.md
  • sippy-ng/CLAUDE.md is excluded by !sippy-ng/CLAUDE.md
📒 Files selected for processing (38)
  • .apm/instructions/backend.instructions.md
  • .apm/instructions/frontend.instructions.md
  • apm.lock.yaml
  • config/openshift.yaml
  • pkg/api/README.md
  • pkg/api/componentreadiness/dataprovider/bigquery/releasedates.go
  • pkg/api/componentreadiness/dataprovider/postgres/provider.go
  • pkg/api/componentreadiness/queryparamparser_test.go
  • pkg/api/componentreadiness/triage_test.go
  • pkg/api/componentreadiness/utils/utils_test.go
  • pkg/api/job_runs.go
  • pkg/api/jobs.go
  • pkg/api/releases.go
  • pkg/api/releases_test.go
  • pkg/api/test_analysis.go
  • pkg/apis/api/types.go
  • pkg/apis/sippy/v1/types.go
  • pkg/apis/sippyprocessing/v1/types.go
  • pkg/db/db.go
  • pkg/db/views.go
  • pkg/filter/filterable.go
  • pkg/sippyserver/chat_conversations.go
  • pkg/sippyserver/parameters.go
  • pkg/sippyserver/server.go
  • pkg/testidentification/ocp_variants.go
  • pkg/util/utils.go
  • pkg/util/utils_test.go
  • pkg/variantregistry/snapshot.yaml
  • sippy-ng/src/App.js
  • sippy-ng/src/build_clusters/BuildClusterDetails.js
  • sippy-ng/src/component_readiness/RegressedTestsPanel.js
  • sippy-ng/src/component_readiness/TriagedRegressionTestList.js
  • sippy-ng/src/datagrid/GridToolbarFilterItem.js
  • sippy-ng/src/datagrid/utils.js
  • sippy-ng/src/helpers.js
  • sippy-ng/src/jobs/JobRunsTable.js
  • sippy-ng/src/jobs/JobStackedChart.js
  • sippy-ng/src/jobs/JobsDetail.js
✅ Files skipped from review due to trivial changes (6)
  • pkg/db/db.go
  • pkg/api/componentreadiness/queryparamparser_test.go
  • .apm/instructions/frontend.instructions.md
  • .apm/instructions/backend.instructions.md
  • apm.lock.yaml
  • pkg/api/README.md
🚧 Files skipped from review as they are similar to previous changes (31)
  • pkg/api/componentreadiness/dataprovider/bigquery/releasedates.go
  • pkg/sippyserver/chat_conversations.go
  • pkg/api/componentreadiness/utils/utils_test.go
  • pkg/util/utils_test.go
  • pkg/api/job_runs.go
  • sippy-ng/src/jobs/JobStackedChart.js
  • sippy-ng/src/datagrid/utils.js
  • pkg/apis/sippy/v1/types.go
  • sippy-ng/src/component_readiness/RegressedTestsPanel.js
  • pkg/db/views.go
  • sippy-ng/src/build_clusters/BuildClusterDetails.js
  • sippy-ng/src/App.js
  • sippy-ng/src/component_readiness/TriagedRegressionTestList.js
  • pkg/testidentification/ocp_variants.go
  • sippy-ng/src/jobs/JobRunsTable.js
  • sippy-ng/src/datagrid/GridToolbarFilterItem.js
  • pkg/api/componentreadiness/dataprovider/postgres/provider.go
  • sippy-ng/src/jobs/JobsDetail.js
  • pkg/api/releases_test.go
  • pkg/util/utils.go
  • pkg/api/componentreadiness/triage_test.go
  • pkg/sippyserver/server.go
  • pkg/apis/sippyprocessing/v1/types.go
  • sippy-ng/src/helpers.js
  • pkg/api/test_analysis.go
  • pkg/api/releases.go
  • pkg/sippyserver/parameters.go
  • pkg/filter/filterable.go
  • pkg/apis/api/types.go
  • pkg/api/jobs.go
  • config/openshift.yaml

Comment thread pkg/variantregistry/snapshot.yaml Outdated
@mstaeble
mstaeble force-pushed the trt-2364-timestamp-consistency branch 5 times, most recently from bc4cd1a to c07f3b7 Compare June 30, 2026 17:15
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e

@mstaeble
mstaeble force-pushed the trt-2364-timestamp-consistency branch from 9ba64f3 to 357750a Compare August 20, 2026 01:27
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e

@neisw

neisw commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 20, 2026
Replace epoch millisecond integers with proper timestamp and date types
across the database schema, API layer, and frontend.

Backend:
- Enforce UTC timezone on all PostgreSQL connections via pgx RuntimeParams
- Change matview timestamp from bigint epoch to TIMESTAMP WITH TIME ZONE
- Use civil.Date for date-only fields (GA dates, development start dates,
  CountByDate, jobDetailAPIResult start/end, ReleaseDefinition)
- Change CalendarEvent.Start/End from string to time.Time
- Change ChatConversationResponse.CreatedAt from string to time.Time
- Change JobRun.Timestamp from int to time.Time (RFC 3339 in JSON)
- Remove epoch extraction from SQL filters; compare timestamptz directly
- Handle ColumnTypeTimestamp in Compare() via GetNumericalValue
- Fix PrintJobsReportFromDB to strip job-run filters (timestamp, cluster)
  before querying the prow_jobs table (pre-existing bug)
- Add filter.StripJobRunFilters for reusable job-run filter removal
- Fix GetTestAnalysisOverallFromDB to use reportEnd instead of time.Now()
  for consistent date windowing with pinned time (pre-existing bug)

Frontend:
- Use ISO 8601 strings for timestamp filter values throughout
- Remove dead ga_dates timezone hack in App.js
- Use valueGetter returning Date objects for DataGrid timestamp columns
- Add type: 'date' to all date/timestamp DataGrid columns
- Preserve 'not' flag when updating date filter values
- Rewrite JobsDetail day bucketing with Temporal.PlainDate
- Update DateTimePicker and filter display to use ISO strings

Documentation:
- Add timestamp/date type guidelines to backend and frontend instructions
- Update API docs to show RFC 3339 and YYYY-MM-DD formats

Note: production databases should also have their default timezone set to
UTC via ALTER DATABASE <name> SET timezone = 'UTC'.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mstaeble
mstaeble force-pushed the trt-2364-timestamp-consistency branch from 357750a to 1f41be4 Compare August 20, 2026 19:17
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Aug 20, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e

@neisw

neisw commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 20, 2026
@openshift-ci

openshift-ci Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: mstaeble, neisw

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci

openshift-ci Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

@mstaeble: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@openshift-merge-bot
openshift-merge-bot Bot merged commit 0f92a32 into openshift:main Aug 20, 2026
12 checks passed
@mstaeble
mstaeble deleted the trt-2364-timestamp-consistency branch August 20, 2026 21:06
redhat-chai-bot added a commit to redhat-chai-bot/api that referenced this pull request Aug 21, 2026
Sippy PR openshift/sippy#3716 changed the timestamp column backing /api/jobs/runs to a raw timestamptz Postgres type. BuildSippyJobRunsForJobURL() was sending the >= filter value as epoch milliseconds (fmt.Sprintf("%d", timestamp.UnixMilli())), which Postgres cannot parse as a timestamp, so the /api/jobs/runs call failed.

Send the filter value as an RFC 3339 string (timestamp.UTC().Format(time.RFC3339), e.g. "2026-08-07T00:00:00Z") which Postgres parses natively as timestamptz.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
redhat-chai-bot added a commit to redhat-chai-bot/ai-helpers that referenced this pull request Aug 21, 2026
Sippy PR openshift/sippy#3716 (commit 0f92a3222) changed the
/api/jobs/runs `timestamp` column from an epoch-millisecond bigint to a
native Postgres timestamptz, serialized as an RFC 3339 string (e.g.
"2026-08-14T00:01:05Z"). Filtering on `timestamp` now compares against a
timestamptz, so epoch-ms filter values fail Postgres parsing.

fetch-prow-job-runs:
- Rename since_millis() -> since_rfc3339(); it now returns an RFC 3339 UTC
  string instead of epoch-ms.
- build_filter() passes the RFC 3339 string straight through as the
  timestamp filter value.
- Rework/extend tests to assert RFC 3339 output.

analyze-disruption:
- Add _parse_rfc3339_ms(): parses the RFC 3339 timestamp strings Sippy now
  returns to epoch-ms for dedup arithmetic and sorting. It accepts only
  RFC 3339 strings; any non-string, empty, or unparseable value falls back
  to 0 instead of raising (no int/float passthrough).
- build_sippy_filter() emits the RFC 3339 timestamp value.
- select_representative_runs(), format_timestamp(), and the main() sort key
  parse via _parse_rfc3339_ms().
- Compute the lookback cutoff as an RFC 3339 string.
- Rewrite every test fixture to use RFC 3339 timestamp strings, preserving
  the exact time deltas the 60s same-job / 5s cross-job dedup thresholds
  rely on. Drop the int/float passthrough tests, the epoch-ms
  format_timestamp test, and the now-duplicative RFC-3339-specific dedup
  tests (the migrated fixtures cover those paths directly).

Verified end-to-end against the live Sippy API, which returns RFC 3339
timestamps and accepts the RFC 3339 filter.

Bump ci plugin 0.0.85 -> 0.0.86 and regenerate marketplace.json/docs.
The docs/index.html regeneration also picks up the previously undocumented
openshift-developer has-review-work skill (docs were already stale at HEAD).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
redhat-chai-bot added a commit to redhat-chai-bot/ai-helpers that referenced this pull request Aug 21, 2026
Sippy PR openshift/sippy#3716 (commit 0f92a3222) changed the
/api/jobs/runs `timestamp` column from an epoch-millisecond bigint to a
native Postgres timestamptz, serialized as an RFC 3339 string (e.g.
"2026-08-14T00:01:05Z"). Filtering on `timestamp` now compares against a
timestamptz, so epoch-ms filter values fail Postgres parsing.

fetch-prow-job-runs:
- Rename since_millis() -> since_rfc3339(); it now returns an RFC 3339 UTC
  string instead of epoch-ms.
- build_filter() passes the RFC 3339 string straight through as the
  timestamp filter value.
- Rework/extend tests to assert RFC 3339 output.

analyze-disruption:
- Add _parse_rfc3339_ms(): parses the RFC 3339 timestamp strings Sippy now
  returns to epoch-ms for dedup arithmetic and sorting. It accepts only
  RFC 3339 strings; any non-string, empty, or unparseable value falls back
  to 0 instead of raising (no int/float passthrough).
- build_sippy_filter() emits the RFC 3339 timestamp value.
- select_representative_runs(), format_timestamp(), and the main() sort key
  parse via _parse_rfc3339_ms().
- Compute the lookback cutoff as an RFC 3339 string.
- Rewrite every test fixture to use RFC 3339 timestamp strings, preserving
  the exact time deltas the 60s same-job / 5s cross-job dedup thresholds
  rely on. Drop the int/float passthrough tests, the epoch-ms
  format_timestamp test, and the now-duplicative RFC-3339-specific dedup
  tests (the migrated fixtures cover those paths directly).

Verified end-to-end against the live Sippy API, which returns RFC 3339
timestamps and accepts the RFC 3339 filter.

Bump ci plugin 0.0.85 -> 0.0.86 and regenerate marketplace.json/docs.
The docs/index.html regeneration also picks up the previously undocumented
openshift-developer has-review-work skill (docs were already stale at HEAD).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
redhat-chai-bot added a commit to redhat-chai-bot/ai-helpers that referenced this pull request Aug 21, 2026
Sippy PR openshift/sippy#3716 (commit 0f92a3222) changed the
/api/jobs/runs `timestamp` column from an epoch-millisecond bigint to a
native Postgres timestamptz, serialized as an RFC 3339 string (e.g.
"2026-08-14T00:01:05Z"). Filtering on `timestamp` now compares against a
timestamptz, so epoch-ms filter values fail Postgres parsing.

Handle timestamps as datetimes end to end: parse RFC 3339 strings to
timezone-aware UTC datetimes at the API boundary, run dedup/sort
arithmetic on datetimes, and format back to RFC 3339 only at the query
boundary.

fetch-prow-job-runs:
- since_cutoff(hours, now=None) returns the lookback cutoff as a
  timezone-aware UTC datetime; now defaults to the current UTC time and
  accepts a datetime for test injection.
- build_filter() formats the datetime `since` to an RFC 3339 string for
  the timestamp filter value.

analyze-disruption:
- _parse_timestamp() parses Sippy's RFC 3339 timestamp strings to
  timezone-aware UTC datetimes, falling back to the 1970-01-01 UTC epoch
  sentinel for missing or unparseable values instead of raising.
- select_representative_runs() stores datetimes and dedups with timedelta
  arithmetic (60s same-job, 5s cross-job).
- build_sippy_filter() formats the datetime cutoff to RFC 3339,
  format_timestamp() reformats to a short display form, and main()
  computes the cutoff as a datetime and sorts rows by parsed datetime.

Tests use literal RFC 3339 fixtures and datetime assertions.

Bump ci plugin 0.0.85 -> 0.0.86 and regenerate marketplace.json/docs.
The docs/index.html regeneration also picks up the previously undocumented
openshift-developer has-review-work skill (docs were already stale at HEAD).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
redhat-chai-bot added a commit to redhat-chai-bot/ai-helpers that referenced this pull request Aug 21, 2026
Sippy PR openshift/sippy#3716 (commit 0f92a3222) changed the
/api/jobs/runs `timestamp` column from an epoch-millisecond bigint to a
native Postgres timestamptz, serialized as an RFC 3339 string (e.g.
"2026-08-14T00:01:05Z"). Filtering on `timestamp` now compares against a
timestamptz, so epoch-ms filter values fail Postgres parsing.

Handle timestamps as datetimes end to end: parse RFC 3339 strings to
timezone-aware UTC datetimes at the API boundary, run dedup/sort
arithmetic on datetimes, and format back to RFC 3339 only at the query
boundary.

fetch-prow-job-runs:
- since_cutoff(hours, now=None) returns the lookback cutoff as a
  timezone-aware UTC datetime; now defaults to the current UTC time and
  accepts a datetime for test injection.
- build_filter() formats the datetime `since` to an RFC 3339 string for
  the timestamp filter value.

analyze-disruption:
- _parse_timestamp() parses Sippy's RFC 3339 timestamp strings to
  timezone-aware UTC datetimes, falling back to the 1970-01-01 UTC epoch
  sentinel for missing or unparseable values instead of raising.
- select_representative_runs() stores datetimes and dedups with timedelta
  arithmetic (60s same-job, 5s cross-job).
- build_sippy_filter() formats the datetime cutoff to RFC 3339,
  format_timestamp() reformats to a short display form, and main()
  computes the cutoff as a datetime and sorts rows by parsed datetime.

Tests use literal RFC 3339 fixtures and datetime assertions.

Bump ci plugin 0.0.85 -> 0.0.86 and regenerate marketplace.json/docs.
The docs/index.html regeneration also picks up the previously undocumented
openshift-developer has-review-work skill (docs were already stale at HEAD).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
redhat-chai-bot added a commit to redhat-chai-bot/ai-helpers that referenced this pull request Aug 21, 2026
Sippy PR openshift/sippy#3716 (commit 0f92a3222) changed the
/api/jobs/runs `timestamp` column from an epoch-millisecond bigint to a
native Postgres timestamptz, serialized as an RFC 3339 string (e.g.
"2026-08-14T00:01:05Z"). Filtering on `timestamp` now compares against a
timestamptz, so epoch-ms filter values fail Postgres parsing.

Handle timestamps as datetimes end to end: parse RFC 3339 strings to
timezone-aware UTC datetimes at the API boundary, run dedup/sort
arithmetic on datetimes, and format back to RFC 3339 only at the query
boundary.

fetch-prow-job-runs:
- since_cutoff(hours, now=None) returns the lookback cutoff as a
  timezone-aware UTC datetime; now defaults to the current UTC time and
  accepts a datetime for test injection.
- build_filter() formats the datetime `since` to an RFC 3339 string for
  the timestamp filter value.

analyze-disruption:
- _parse_timestamp() parses Sippy's RFC 3339 timestamp strings to
  timezone-aware UTC datetimes, falling back to the 1970-01-01 UTC epoch
  sentinel for missing or unparseable values instead of raising.
- select_representative_runs() stores datetimes and dedups with timedelta
  arithmetic (60s same-job, 5s cross-job).
- build_sippy_filter() formats the datetime cutoff to RFC 3339,
  format_timestamp() reformats to a short display form, and main()
  computes the cutoff as a datetime and sorts rows by parsed datetime.

Tests use literal RFC 3339 fixtures and datetime assertions.

Bump ci plugin 0.0.85 -> 0.0.86 and regenerate marketplace.json/docs.
The docs/index.html regeneration also picks up the previously undocumented
openshift-developer has-review-work skill (docs were already stale at HEAD).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
redhat-chai-bot added a commit to redhat-chai-bot/ai-helpers that referenced this pull request Aug 21, 2026
Sippy PR openshift/sippy#3716 (commit 0f92a3222) changed the
/api/jobs/runs `timestamp` column from an epoch-millisecond bigint to a
native Postgres timestamptz, serialized as an RFC 3339 string (e.g.
"2026-08-14T00:01:05Z"). Filtering on `timestamp` now compares against a
timestamptz, so epoch-ms filter values fail Postgres parsing.

Handle timestamps as datetimes end to end: parse RFC 3339 strings to
timezone-aware UTC datetimes at the API boundary, run dedup/sort
arithmetic on datetimes, and format back to RFC 3339 only at the query
boundary.

fetch-prow-job-runs:
- since_cutoff(hours, now=None) returns the lookback cutoff as a
  timezone-aware UTC datetime; now defaults to the current UTC time and
  accepts a datetime for test injection.
- build_filter() formats the datetime `since` to an RFC 3339 string for
  the timestamp filter value.

analyze-disruption:
- _parse_timestamp() parses Sippy's RFC 3339 timestamp strings to
  timezone-aware UTC datetimes, falling back to the 1970-01-01 UTC epoch
  sentinel for missing or unparseable values instead of raising.
- select_representative_runs() stores datetimes and dedups with timedelta
  arithmetic (60s same-job, 5s cross-job).
- build_sippy_filter() formats the datetime cutoff to RFC 3339,
  format_timestamp() reformats to a short display form, and main()
  computes the cutoff as a datetime and sorts rows by parsed datetime.

Tests use literal RFC 3339 fixtures and datetime assertions.

Bump ci plugin 0.0.85 -> 0.0.86 and regenerate marketplace.json/docs.
The docs/index.html regeneration also picks up the previously undocumented
openshift-developer has-review-work skill (docs were already stale at HEAD).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
redhat-chai-bot added a commit to redhat-chai-bot/ai-helpers that referenced this pull request Aug 21, 2026
Sippy PR openshift/sippy#3716 (commit 0f92a3222) changed the
/api/jobs/runs `timestamp` column from an epoch-millisecond bigint to a
native Postgres timestamptz, serialized as an RFC 3339 string (e.g.
"2026-08-14T00:01:05Z"). Filtering on `timestamp` now compares against a
timestamptz, so epoch-ms filter values fail Postgres parsing.

Handle timestamps as datetimes end to end: parse RFC 3339 strings to
timezone-aware UTC datetimes at the API boundary, run dedup arithmetic
on datetimes, and format back to RFC 3339 only at the query boundary.

fetch-prow-job-runs:
- since_cutoff(hours, now=None) returns the lookback cutoff as a
  timezone-aware UTC datetime; now defaults to the current UTC time and
  accepts a datetime for test injection.
- build_filter() formats the datetime `since` to an RFC 3339 UTC string
  (Z suffix) for the timestamp filter value.

analyze-disruption:
- _parse_timestamp() parses Sippy's RFC 3339 timestamp strings to
  timezone-aware UTC datetimes, falling back to the 1970-01-01 UTC epoch
  sentinel for missing or unparseable values instead of raising.
- select_representative_runs() stores datetimes and dedups with timedelta
  arithmetic (60s same-job, 5s cross-job).
- build_sippy_filter() formats the datetime cutoff to an RFC 3339 UTC
  string (Z suffix). format_timestamp() reformats a timestamp to a short
  display form and returns an empty string for falsy input. main()
  computes the cutoff as a datetime and sorts rows lexicographically by
  their RFC 3339 timestamp string (Z-suffixed UTC strings sort
  chronologically, so no parsing is needed).

Tests use literal RFC 3339 fixtures and datetime assertions.

Bump ci plugin 0.0.85 -> 0.0.86 and regenerate marketplace.json/docs.
The docs/index.html regeneration also picks up the previously undocumented
openshift-developer has-review-work skill (docs were already stale at HEAD).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
redhat-chai-bot added a commit to redhat-chai-bot/ai-helpers that referenced this pull request Aug 21, 2026
Sippy PR openshift/sippy#3716 (commit 0f92a3222) changed the
/api/jobs/runs `timestamp` column from an epoch-millisecond bigint to a
native Postgres timestamptz, serialized as an RFC 3339 string (e.g.
"2026-08-14T00:01:05Z"). Filtering on `timestamp` now compares against a
timestamptz, so epoch-ms filter values fail Postgres parsing.

Handle timestamps as datetimes end to end: parse RFC 3339 strings to
timezone-aware UTC datetimes at the API boundary, run dedup arithmetic
on datetimes, and format back to RFC 3339 only at the query boundary.

fetch-prow-job-runs:
- since_cutoff(hours, now=None) returns the lookback cutoff as a
  timezone-aware UTC datetime; now defaults to the current UTC time and
  accepts a datetime for test injection.
- build_filter() formats the datetime `since` to an RFC 3339 UTC string
  (Z suffix) for the timestamp filter value.

analyze-disruption:
- _parse_timestamp() parses Sippy's RFC 3339 timestamp strings to
  timezone-aware UTC datetimes, falling back to the 1970-01-01 UTC epoch
  sentinel for missing or unparseable values instead of raising.
- select_representative_runs() stores datetimes and dedups with timedelta
  arithmetic (60s same-job, 5s cross-job).
- build_sippy_filter() formats the datetime cutoff to an RFC 3339 UTC
  string (Z suffix). format_timestamp() reformats a timestamp to a short
  display form and returns an empty string for falsy input. main()
  computes the cutoff as a datetime and sorts rows lexicographically by
  their RFC 3339 timestamp string (Z-suffixed UTC strings sort
  chronologically, so no parsing is needed).

Tests use literal RFC 3339 fixtures and datetime assertions.

Bump ci plugin 0.0.85 -> 0.0.86 and regenerate marketplace.json/docs.
The docs/index.html regeneration also picks up the previously undocumented
openshift-developer has-review-work skill (docs were already stale at HEAD).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
redhat-chai-bot added a commit to redhat-chai-bot/ai-helpers that referenced this pull request Aug 21, 2026
Sippy PR openshift/sippy#3716 (commit 0f92a3222) changed the
/api/jobs/runs `timestamp` column from an epoch-millisecond bigint to a
native Postgres timestamptz, serialized as an RFC 3339 string (e.g.
"2026-08-14T00:01:05Z"). Filtering on `timestamp` now compares against a
timestamptz, so epoch-ms filter values fail Postgres parsing.

Handle timestamps as datetimes end to end: parse RFC 3339 strings to
timezone-aware UTC datetimes at the API boundary, run dedup arithmetic
on datetimes, and format back to RFC 3339 only at the query boundary.

fetch-prow-job-runs:
- since_cutoff(hours, now=None) returns the lookback cutoff as a
  timezone-aware UTC datetime; now defaults to the current UTC time and
  accepts a datetime for test injection.
- build_filter() formats the datetime `since` to an RFC 3339 UTC string
  (Z suffix) for the timestamp filter value.

analyze-disruption:
- _parse_timestamp() parses Sippy's RFC 3339 timestamp strings to
  timezone-aware UTC datetimes, also accepting numeric epoch-milliseconds
  and treating timezone-naive strings as UTC, and falling back to the
  1970-01-01 UTC epoch sentinel for missing or unparseable values instead
  of raising.
- select_representative_runs() stores datetimes and dedups with timedelta
  arithmetic (60s same-job, 5s cross-job).
- build_sippy_filter() formats the datetime cutoff to an RFC 3339 UTC
  string (Z suffix). format_timestamp() reformats a timestamp to a short
  display form and returns an empty string for falsy input. main()
  computes the cutoff as a datetime and sorts merged rows newest-first
  with _parse_timestamp, so ordering is by actual time regardless of
  timestamp representation.

Tests use literal RFC 3339 fixtures and datetime assertions.

Bump ci plugin 0.0.85 -> 0.0.86 and regenerate marketplace.json/docs.
The docs/index.html regeneration also picks up the previously undocumented
openshift-developer has-review-work skill (docs were already stale at HEAD).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
redhat-chai-bot added a commit to redhat-chai-bot/ai-helpers that referenced this pull request Aug 21, 2026
Sippy PR openshift/sippy#3716 (commit 0f92a3222) changed the
/api/jobs/runs `timestamp` column from an epoch-millisecond bigint to a
native Postgres timestamptz, serialized as an RFC 3339 string (e.g.
"2026-08-14T00:01:05Z"). Filtering on `timestamp` now compares against a
timestamptz, so epoch-ms filter values fail Postgres parsing.

Handle timestamps as datetimes end to end: parse RFC 3339 strings to
timezone-aware UTC datetimes at the API boundary, run dedup arithmetic
on datetimes, and format back to RFC 3339 only at the query boundary.

fetch-prow-job-runs:
- since_cutoff(hours, now=None) returns the lookback cutoff as a
  timezone-aware UTC datetime; now defaults to the current UTC time and
  accepts a datetime for test injection.
- build_filter() formats the datetime `since` to an RFC 3339 UTC string
  (Z suffix) for the timestamp filter value.

analyze-disruption:
- _parse_timestamp() parses Sippy's RFC 3339 timestamp strings to
  timezone-aware UTC datetimes, also accepting numeric epoch-milliseconds
  and treating timezone-naive strings as UTC, and falling back to the
  1970-01-01 UTC epoch sentinel for missing or unparseable values instead
  of raising.
- select_representative_runs() stores datetimes and dedups with timedelta
  arithmetic (60s same-job, 5s cross-job).
- build_sippy_filter() formats the datetime cutoff to an RFC 3339 UTC
  string (Z suffix). format_timestamp() reformats a timestamp to a short
  display form and returns an empty string for falsy input. main()
  computes the cutoff as a datetime and sorts merged rows newest-first
  with _parse_timestamp, so ordering is by actual time regardless of
  timestamp representation.

Tests use literal RFC 3339 fixtures and datetime assertions.

Bump ci plugin 0.0.85 -> 0.0.86 and regenerate marketplace.json/docs.
The docs/index.html regeneration also picks up the previously undocumented
openshift-developer has-review-work skill (docs were already stale at HEAD).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants