Skip to content

fix(stand): date-independent journeys + seed; e2e-stand runs on PRs from the checkout - #2453

Merged
ktursunov merged 11 commits into
mainfrom
fix/stand-date-independent
Aug 12, 2026
Merged

fix(stand): date-independent journeys + seed; e2e-stand runs on PRs from the checkout#2453
ktursunov merged 11 commits into
mainfrom
fix/stand-date-independent

Conversation

@ktursunov

@ktursunov ktursunov commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

What

The two evidence drill-down journeys (test_git_commit_bucket_opens_and_exports_supporting_data, test_table_total_opens_supporting_data_for_the_whole_period) fail on some calendar dates and pass on others — they are red in the current nightlies and in dispatch run 31560385144.

Why

Both page objects click the first body row of a timeseries table. The first row of a trailing-month window is the leading partial week bucket, whose overlap with the window can be a single day. A bucket with no activity renders , and MetricTableValue only wraps a valued cell in a <button> — so on those dates there is nothing to click and the locator times out after 30 s. The seeded activity is weekday-shaped and Poisson-drawn, so whether the leading bucket is drillable depends on which day the window starts (weekend-only overlap being the common empty case).

Fix

  • Page objects target the first drillable cell instead of the first row: open_bucket_evidence / open_total_row_evidence click the row group's first button; open_first_commit_bucket filters to the first row whose Commits cell carries a button, staying pinned to that column so the dialog opened is the one the test names.

  • Git seed floors commits at one per person-day (weekday_multiplier still shapes volume), so every bucket of the git surface is drillable whatever day the stand is seeded. PROFILE.md regenerated for the new seed_revision.

  • Seed link parity (review follow-up): the commit floor had broken the RNG re-derivation contract — seed_class_git_pull_requests_commits still computed the day's commit count with the raw Poisson draw, so a zero-draw day carried a floored commit with no PR-link rows, and a short day (fewer commits than PRs) dealt empty slices to the tail PRs; either way the PR loses its author attribution in gold's pr_commit_emails join. Both generators now share one _daily_commit_count helper and the round-robin deal wraps on short days. tests/test_git_links.py locks the parity at the emitted-row level, with the anchor pinned so the fixture window provably contains a zero-draw PR day.

CI workflow (absorbed from #2458, then extended)

e2e-stand.yml is converted from a merge-queue-only gate into a per-PR one, and the stand's scope is broadened to any change under tests/**, src/backend/**, or src/frontend/**:

  • Runs on PRs for real. The event guard that skipped every job on pull_request is gone: a PR whose diff matches the new paths: filter (mirroring the changes job's regex — the two lists are documented as kept in sync) runs api-smoke and ui-journeys, with superseded runs cancelled by the concurrency group. merge_group (no paths: support), the nightly, and dispatch keep working via the changes job. While the paths filter exists, Stand E2E can only be made required on merge_group, never at PR level — a required check whose workflow never triggers reports as pending forever; the current main ruleset requires neither, so nothing breaks today.
  • Backend diffs build the backend. test-stand up refuses a tree that changes src/backend/ rather than testing it against main's pulled images, so changes reports a backend flag and the lanes translate it into up --build-backend plus a wider timeout.
  • ui-journeys runs host-side from the checkout on every event, so the lane always tests the ref's own test code. It previously ran the suite baked into the published insight-ui-tests:latest image, which only moves on a main push — a PR lane therefore ran main's old test code against the PR's stand and could not go green on the very PR fixing it. The host's localhost:<port> satisfies the same __Host- cookie origin constraint the image's netns join existed for.
  • The ui-tests image is removed entirely (Dockerfile, build/publish jobs, change filters, tests/versions.yaml sync ledger): after checkout mode, its only consumer was the pipeline validating the image itself. test-stand test --image <ref> remains as a mechanism for a locally built runner; insight-ui-tests stays in ghcr-cleanup so published versions keep getting pruned.
  • The seed package's new tests are pytest-style; build-images.yml's seed validation installs pytest transiently into the throwaway container, so the published seed image still ships without it.

Verification

Against a freshly re-seeded compose stand: both previously failing journeys pass, and the full tests/stand suite is green — 296 passed, 3 xfailed, 2 xpassed (the xpasses are the known #2361 flake entries).

This branch's UI-test code was also run host-side against a live stand seeded without the commit floor on a date where CI reproduced the flake — 17/17 journeys pass, proving the locator half absorbs the undrillable leading bucket on its own. And the converted workflow demonstrates itself on this PR: the PR-triggered e2e-stand runs execute both lanes from this branch's checkout, 17/17 ui-journeys, Stand E2E green.

Summary by CodeRabbit

  • Bug Fixes

    • Improved activity generation so eligible people receive at least one commit per day while preserving realistic volume limits.
    • Improved evidence navigation in group and person views by reliably opening the first available drill-down option, including total rows and partial-week data.
  • Documentation

    • Updated the documented seed revision to reflect the latest generated dataset.

…ndent

The two evidence drill-down journeys clicked the FIRST body row of a
timeseries table. The first row of a trailing-month window is the leading
partial week bucket, whose overlap with the window can be a single day —
and a day with no activity renders "—" with no button (the frontend only
wraps a valued cell in one). Whether that click ever lands therefore
depended on which calendar day the run started, which is why the stand
lane went red on some dates and not others.

Two sides of the fix:

- Page objects target the first DRILLABLE cell: open_bucket_evidence and
  open_total_row_evidence click the row group's first button, and
  open_first_commit_bucket filters to the first row whose Commits cell
  carries one, staying pinned to the Commits column so the dialog opened
  is the one named.
- The git seed floors commits at one per person-day (weekday_multiplier
  still shapes volume), so every bucket of the git surface is drillable
  whatever day the window starts on. PROFILE.md regenerated for the new
  seed_revision.

Verified against a freshly re-seeded compose stand: the two previously
failing journeys pass and the full suite is green (296 passed, 3 xfailed,
2 xpassed — the xpasses are the known #2361 flake entries).

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
@ktursunov
ktursunov requested a review from a team as a code owner August 12, 2026 05:35
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The seed generator now creates at least one commit per eligible person per day. UI page objects now locate drillable evidence controls across partial or empty leading buckets and footer rows.

Changes

Seed generation and evidence navigation

Layer / File(s) Summary
Daily commit generation
src/ingestion/tools/seed/PROFILE.md, src/ingestion/tools/seed/insight_seed/generators/git.py
The Git seed generator clamps daily commit counts to at least one while retaining Poisson volume and COMMITS_CAP. The documented seed revision is updated.
Evidence navigation
tests/stand/ui/pages/group_dialog.py, tests/stand/ui/pages/person_view.py
Evidence navigation searches body and footer rowgroups for available buttons. Commit bucket navigation skips leading rows without a drillable Commits button.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

Suggested reviewers: cyberantonz, aleksdotbar

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title accurately describes the date-independent journey and seed fixes, but it also claims PR checkout execution changes that are not present in the changeset. Remove the unsupported “e2e-stand runs on PRs from the checkout” clause or include the corresponding workflow changes.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/stand-date-independent

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

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 `@src/ingestion/tools/seed/insight_seed/generators/git.py`:
- Around line 91-97: Apply the same minimum-one commit-count rule used by
seed_class_git_commits to seed_class_git_pull_requests_commits, preferably by
reusing a shared helper, so zero Poisson draws still generate the commit index 0
and its PR link. Add a regression test covering a zero Poisson draw and
confirming the commit and link are created.
🪄 Autofix

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fc461118-8d01-4b5c-be9e-ab18b9ca8595

📥 Commits

Reviewing files that changed from the base of the PR and between 825061d and e76ef7e.

📒 Files selected for processing (4)
  • src/ingestion/tools/seed/PROFILE.md
  • src/ingestion/tools/seed/insight_seed/generators/git.py
  • tests/stand/ui/pages/group_dialog.py
  • tests/stand/ui/pages/person_view.py

Comment thread src/ingestion/tools/seed/insight_seed/generators/git.py Outdated
@ktursunov

Copy link
Copy Markdown
Contributor Author

Dispatch run on this branch: 31567069878 — api-smoke ✅, ui-journeys 16/17 with test_table_total_opens_supporting_data_for_the_whole_period still red. That residual failure is expected and does not indicate the fix is wrong:

The ui-journeys lane runs the suite baked into the published insight-ui-tests:latest image ("pulled, never built" — see the workflow comment), and :latest is tagged only on a main push. So the lane exercised main's page objects, not this branch's — the failing call log shows the old row.first locator. Two confirmations inside the same run:

  • The git journey went green in CI for the first time in days with the old locator still in place — that is the seed floor working: the leading bucket's Commits cell is now always drillable, so even a first-row click lands.
  • The table-total journey ran the old locator against the task-delivery table, whose sparse issue-closes legitimately leave the leading partial bucket (no floor there, deliberately — close volume is realism the seed keeps).

The page-object fix is proven on a live stand by a host-side run of this branch's code: both previously failing journeys pass and the full tests/stand suite is green (296 passed / 3 xfailed / 2 xpassed). Once this merges, build-images.yml republishes the ui-tests image from main and the lane picks the fixed locators up.

…nd and tests

Mirror the changes job's relevance regex as an explicit paths: list on the
pull_request trigger, and broaden both in step: any change under tests/,
src/backend/ or src/frontend/ (not just tests/stand, tests/lib and the
frontend helm chart) now counts as stand-relevant.

On pull_request every job still skips, so the filter only prunes no-op
runs from the Actions tab; the changes job keeps doing the same filtering
for merge_group, which supports no paths: key. While the filter exists,
Stand E2E can only be required on merge_group, never at PR level - a
required check whose workflow never triggers reports as pending forever.
The comments record that constraint.

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
ktursunov and others added 3 commits August 12, 2026 15:06
The commit floor broke the RNG re-derivation contract:
seed_class_git_pull_requests_commits still computed the day's commit
count with the raw Poisson draw, so on a zero-draw day class_git_commits
carried a floored commit while the links table skipped the day entirely
- and any PR created that day lost its author attribution in gold's
pr_commit_emails join. Both generators now call one _daily_commit_count
helper.

The regression test also surfaced the adjacent shortfall: a day with
fewer commits than PRs dealt empty slices to the tail PRs, with the same
linkless consequence. The round-robin now wraps on short days - a link
per PR outranks never double-linking a commit.

Unit tests lock the parity at the emitted-row level and pin the anchor
so the fixture window provably contains a zero-draw PR day. PROFILE.md
regenerated (seed_revision tracks the generator source).

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
@ktursunov ktursunov changed the title fix(stand): date-independent drill-down journeys and git seed fix(stand): date-independent drill-down journeys + seed, e2e-stand paths hardening Aug 12, 2026
The lanes previously skipped on every pull_request by design - the
stand gated only the merge queue, nightly and dispatch, and a PR run
existed solely so the check could report a skip-as-pass. The stand must
go with any change it covers, so the event guard is gone: a PR whose
diff matches the paths filter now runs api-smoke and ui-journeys for
real, with superseded runs cancelled by the concurrency group.

test-stand up refuses a tree that changes src/backend/ rather than
testing it against main's pulled images, so the changes job now also
reports whether the diff touches the backend; the lanes turn that into
up --build-backend and a wider timeout.

Also: the seed package's new link-parity tests are reworked to pytest
idiom. pytest stays out of the published seed image - build-images.yml
installs it transiently into the throwaway validation container, which
still runs the tests against exactly the published package.

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
@ktursunov
ktursunov marked this pull request as draft August 12, 2026 07:42
auto-merge was automatically disabled August 12, 2026 07:42

Pull request was converted to draft

Konstantin Tursunov added 5 commits August 12, 2026 15:44
The ui-tests image bakes the suite in and :latest only moves on a main
push, so image mode on a PR ran main's old test code against the PR's
stand - a lane that cannot go green on the very PR that fixes it, and a
red that stops meaning anything. PR, merge-queue and dispatch builds now
run the journeys host-side from the checkout (the stand publishes the
gateway on the runner's localhost, which satisfies the __Host- cookie
origin constraint the netns join existed for). The nightly keeps image
mode: it runs on main, where the baked suite and the checkout agree, so
the published runner itself stays proven daily.

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
The fallback existed for the bootstrap - the first run before a main
push had ever tagged :latest. The image has long been published, the
lane is nightly-only now, and its whole point is to prove the runner
that was actually published; building a local substitute on a failed
pull would test something no developer pulls. A failed pull now fails
the lane loudly, whatever the cause.

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
e2e-stand.yml runs the journeys from the checkout on PR builds and
consumes the ui-tests image solely via the :latest a main push
publishes, so the PR-side build proved an artefact nothing reads. A
broken ui-tests.Dockerfile now surfaces on the main push after merge
instead of on the PR - accepted, the image is nightly-parity-only now.

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
Its last consumer was CI validating the image itself: after the
ui-journeys lane moved to running the suite host-side from the checkout,
nothing pulled it - and a published artefact whose only reader is the
pipeline that publishes it is maintenance without a customer. Removed:
the Dockerfile, the build/merge jobs and ui_tests change filter in
build-images.yml, the nightly image mode and image pull in e2e-stand.yml
(the nightly now runs host-side like every other event), and the
version-sync bookkeeping in tests/versions.yaml. Docs and dev-compose
help updated; the generic --image mode of test-stand test remains for a
locally built runner. insight-ui-tests stays listed in ghcr-cleanup so
already-published versions keep getting pruned.

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
The file was a hand-maintained sync ledger whose job was keeping the
pip playwright pin, the Dockerfile base tag and the image's baked
browser in agreement - and the ui-tests image removal took the last
outside party with it. Nothing reads the file; what remained duplicated
tests/pyproject.toml. The one note worth keeping (workflows' 3.12
setup-python vs the suite's 3.13 floor) moved into the pyproject
comment beside the floor it annotates.

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
@ktursunov
ktursunov marked this pull request as ready for review August 12, 2026 08:26
@ktursunov
ktursunov enabled auto-merge August 12, 2026 08:26
@ktursunov ktursunov changed the title fix(stand): date-independent drill-down journeys + seed, e2e-stand paths hardening fix(stand): date-independent journeys + seed; e2e-stand runs on PRs from the checkout Aug 12, 2026
@ktursunov
ktursunov added this pull request to the merge queue Aug 12, 2026
Merged via the queue into main with commit 37494bf Aug 12, 2026
54 checks passed
@ktursunov
ktursunov deleted the fix/stand-date-independent branch August 12, 2026 10:17
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.

2 participants