Commit Graph
44 Commits
Author SHA1 Message Date
james.maesandCodex a15663f986 ci: centralize QBit source scanning
Co-Authored-By: Codex <noreply@openai.com>
2026-10-21 10:18:23 -05:00
james.maesandCodex fb64a3ecb0 ci: adopt central orb 0.7.12 and stable gates (#24)
Co-authored-by: Codex <noreply@openai.com>
2026-10-21 08:56:13 -05:00
james.maesandCodex a0aef77ae4 ci: centralize rc release completion in qqq orb (#23)
Co-authored-by: Codex <noreply@openai.com>
2026-10-21 02:25:29 -05:00
james.maesandCodex 909652f1f2 ci: adopt shared orb 0.7.11 (#22)
Co-authored-by: Codex <noreply@openai.com>
2026-10-21 00:59:25 -05:00
james.maes 2da172a50e Merge pull request #21 from QRun-IO/feature/central-ci
ci: adopt shared QQQ orb standard
2026-10-20 19:06:55 -05:00
james.maesandCodex 6a05a82221 ci: adopt verified central QQQ orb 0.7.3
Co-Authored-By: Codex <noreply@openai.com>
2026-10-20 19:02:54 -05:00
james.maes ec2e40ba41 Merge pull request #18 from QRun-IO/fix/audit-quota-rotation
fix(scheduling): rotate audit requests across the daily quota
2026-10-19 06:44:10 -05:00
james.maesandOpenAI GPT-6 9ca5f13874 fix(scheduling): rotate audit requests across daily quota
Prioritize never-queued and least-recently-queued page/device pairs using persisted non-quota-skipped history. Scheduled key-page and full audits continue sharing the existing daily allowance with manual requests. Cover odd caps, repeated scheduling, shared allowance and recreated services.

Co-Authored-By: OpenAI GPT-6 <noreply@openai.com>
Signed-off-by: James Maes <james@kof22.com>
2026-10-19 06:41:31 -05:00
james.maes b00fb256b6 Merge pull request #17 from QRun-IO/feature/page-speed-business-home
feat(home): business-only Page Speed home; setup and run queue become admin widgets
2026-10-16 10:19:44 -05:00
james.maesandClaude Opus 5.5 a6c6c99e11 feat(home): business-only Page Speed home; provider setup and run queue become admin widgets
Replace the provider Setup card on the home with a business "not set up"
empty state (no config key names, empty once configured). Setup and Recent
Runs leave the home and become WebPerfWidgets.ADMIN, gated to
<base>.admin.hasAccess with DenyBehavior.HIDDEN, for a host Admin area.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 09:12:51 -05:00
james.maes 0b8b9f8214 Merge pull request #16 from QRun-IO/ci/release-rc-secrets-inherit
ci(release-rc): pass secrets so the shared workflow can sign the RC tag
2026-10-16 08:05:25 -05:00
james.maesandClaude Opus 5.5 483c3d48b3 ci(release-rc): pass secrets to the shared workflow so it can sign the RC tag
QRun-IO/.github#2 adds a tag-and-release job that signs vX with the
QRUN_TAG_SIGNING_KEY secret after Maven Central confirms the artifact.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 16:20:28 -05:00
james.maes 6e6deca794 Merge pull request #15 from QRun-IO/fix/producer-version-from-build
fix: qbit metadata version comes from the build
2026-10-15 01:42:58 -05:00
james.maesandClaude Opus 5.5 9003d1dabe fix: the qbit metadata version comes from the build, not a hardcoded constant
The producer read a literal version, so released artifacts reported a stale
or -SNAPSHOT version. qbit-web-performance.properties (version=${project.version}) is
Maven-filtered and the producer loads it; tests assert producer == bundle ==
artifact version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 01:33:04 -05:00
james.maes c937d753df Merge pull request #14 from QRun-IO/fix/help-bundle-version
fix(help): help bundle version comes from the build, not a hardcoded SNAPSHOT
2026-10-14 22:37:20 -05:00
james.maesandClaude Opus 5.5 ffa50f6964 fix(help): the help bundle carries the artifact version (Maven-filtered) instead of a hardcoded SNAPSHOT
On release branches the bundle's version and the producer's differed, so the
bundle test that asserts they match failed, and released bundles recorded
SNAPSHOT as their provenance. help/*.yaml is now filtered:
version: ${project.version}.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 22:10:27 -05:00
james.maes 8e2ecb3b3f Merge pull request #13 from QRun-IO/feature/help-bundle
feat(help): qbit-web-performance help bundle via QQQ help bundles, with coverage gate
2026-10-14 20:45:30 -05:00
james.maesandClaude Opus 5.5 1e71915f7b feat(help): ship the qbit-web-performance help bundle through QQQ help bundles, with coverage gate
Host-neutral help (deployment-specific facts removed), registered with
HelpBundles, gated by HelpBundleAssertions. QQQ 4.1.0-RC.7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 20:37:23 -05:00
james.maes 8b5b6fde6b Merge pull request #11 from QRun-IO/feature/foreign-keys
feat(schema): foreign keys for every table reference, with orphan quarantine
2026-10-14 18:00:28 -05:00
james.maesandClaude Opus 5.5 588ae52cd9 test(reports): give the old retention report a real run
The foreign key on lab_report.run_id rejects develop's placeholder run 999999,
so the 40-day-old report now belongs to an inserted FAILED run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 17:51:18 -05:00
james.maesandClaude Opus 5.5 cad99545b2 Merge origin/develop into feature/foreign-keys
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 17:49:47 -05:00
james.maes 13eebd9d9c Merge pull request #12 from QRun-IO/feature/tables-populated-defaults
Web performance: table help, Setup card, defaults test, enforce reportRetentionDays
2026-10-14 17:19:51 -05:00
james.maesandClaude Sonnet 5.5 4565a12cd4 fix(reports): prune after commit, hourly and batched; guardrail and test additions
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 17:17:17 -05:00
james.maesandClaude Opus 5.5 dff3077f50 feat(help): table help, Setup card, guardrail tests, enforce reportRetentionDays
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 17:06:48 -05:00
james.maesandClaude Opus 5.5 fb856fdb39 test(schema): take a join's referencing side from its key field
A join's child column is on the side whose field is not the primary key,
so a many-to-one join (child -> parent) is checked on the child too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 16:35:13 -05:00
james.maesandClaude Opus 5.5 7ed9d0b81e feat(schema): foreign keys for every table reference, with orphan quarantine
Changesets 12-26 add a foreign key for each possible-value reference between
the QBit's tables, named fk_<child table>_<column>:

- lab_finding.run_id, lab_report.run_id -> lab_run: CASCADE (owned detail)
- comparison.change_event_id -> change_event: CASCADE (computed for the change)
- regression.cause_change_event_id, lab_run.change_event_id -> change_event,
  regression.first_run_id / checkpoint_run_id -> lab_run: SET NULL (pointers)
- lab_run / lab_finding / regression / comparison .target_id -> target and
  regression.budget_id -> budget: RESTRICT (history is kept, D8; pages and
  budgets are disabled, not deleted; the QBit never deletes either)

Each changeset first records parent-less rows in qqq_fk_quarantine and nulls
them (or, for the NOT NULL run_id columns, copies the row as JSON and deletes
it, PostgreSQL only), and is marked ran when the constraint already exists.
Changeset 12 indexes the foreign key columns that had no leading index.

WebPerfForeignKeyTest runs the changelog with Liquibase on PostgreSQL
(Testcontainers), checks the orphan path and re-run idempotency, and fails
when a table reference in the meta-data has no constraint.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 16:16:35 -05:00
james.maes 5a9ee80b49 Merge pull request #10 from QRun-IO/feature/regressions-budgets
feat(evaluation): write regressions, budget checks, site changes and comparisons (#8)
2026-10-14 11:03:58 -05:00
james.maes e8d226bd69 Merge remote-tracking branch 'origin/develop' into feature/regressions-budgets
# Conflicts:
#	src/main/java/com/kingsrook/qbits/webperf/metadata/WebPerfMetaData.java
2026-10-14 11:01:38 -05:00
james.maesandClaude Opus 5.5 0745f331f4 feat(evaluation): write regressions, budget checks, site changes and comparisons
The regression, budget, change event and comparison tables had list
screens but nothing wrote them; the open regression count was a
hard-coded 0 and budgets were never evaluated.

- Change events: new build ids from the DeployProbe and ChangeEventSource
  events become durable, idempotent change_event rows (event_key);
  lab runs record the deployment (change event) and CDN stage.
- Budgets are evaluated after lab runs and field imports; breaches open
  or refresh regressions.
- Regression detection compares new results with the baseline per page,
  strategy and metric as the design describes, links the likely change,
  confirms before opening, and resolves on recovery. The open regression
  count is real.
- Before/after comparisons are written per change event.
- Dismiss and Mark resolved are standard record actions on regressions.
- Optional alerts through core QAlerts (logging sink without the Alerts
  qbit). QQQ BOM moves to the released 4.1.0-RC.6 for core alerts.
- Changeset 11 adds the progress and identity columns.

Refs #8

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 11:00:41 -05:00
james.maes 78dc868cf4 Merge pull request #7 from QRun-IO/feature/orb-0.6.9
ci: qqq-orb 0.6.9 (refresh SNAPSHOT dependencies)
2026-10-14 10:57:13 -05:00
james.maes 48ad6f6504 Merge pull request #9 from QRun-IO/fix/enum-dropdowns-tested-pages
fix(metadata): dropdowns for enum fields; manual Tested Pages insert works
2026-10-14 10:50:30 -05:00
james.maesandClaude Opus 5.5 54b7d0b39f fix(metadata): dropdowns for enum fields; manual Tested Pages insert
Tier, scope, source, strategy, metric, comparator and severity were free
text, so a typo such as "key" for KEY silently dropped a page from the
daily key-page tests. Each now uses an enum possible value source with
plain labels and the stored values the code already compares against
(no data migration).

Tested Pages offered Insert while URL was not editable but required, so
a manual insert could never succeed. URL is now editable and validated
(absolute https, no credentials or fragment) by TargetCustomizer, which
also fills path, site, source MANUAL and inSitemap false.

Refs #8

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:43:01 -05:00
james.maesandClaude Opus 5.5 fd0abfcb6f ci: qqq-orb 0.6.9 (refresh SNAPSHOT dependencies)
Moves qqq-orb@0.6.8 to qqq-orb@0.6.9, which passes --update-snapshots so cached SNAPSHOT dependencies are re-checked on every build (QRun-IO/qqq-orb#22).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:05:31 -05:00
james.maes 31a33dcbe4 Merge pull request #5 from QRun-IO/feature/release-rc-automation
ci: automate RC releases; hotfix/* pushes no longer publish
2026-10-13 14:43:49 -05:00
james.maesandClaude Opus 5.5 fe2e814300 ci: automate RC releases; hotfix/* pushes no longer publish
Removes publish_hotfix_release: a hotfix/* branch push published a GA
release to Maven Central with no tag or review (QRun-IO/qbit-cdn#12,
QRun-IO/qqq#1121). hotfix/* branches now run test_only; a hotfix
release publishes from a reviewed vX.Y.Z tag through publish_release.
Adds .github/workflows/release-rc.yml (reusable QRun-IO/.github
qbit-release-rc): a manual dispatch, or merging a develop PR labelled
release:rc, merges develop into the release line and the release/* push
runs the existing CircleCI RC publish.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:38:02 -05:00
james.maes 122e9e230b Merge pull request #4 from QRun-IO/feature/ga-only-release-tags
ci: publish only GA tags (vX.Y.Z), never RC tags
2026-10-12 16:01:19 -05:00
james.maesandClaude Opus 5.5 fdd457da0f ci: publish only GA tags (vX.Y.Z), never RC tags
An RC tag matched /v.*/ and the orb republished it as the next RC.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 15:58:22 -05:00
james.maes 957f1ab43d Merge pull request #1 from QRun-IO/chore/qrun-repo-standard
chore: adopt the QRun qbit repository standard
2026-10-12 14:54:45 -05:00
james.maesandClaude Opus 5.5 84fd23510e chore: adopt the QRun qbit repository standard
Add the standard repository files (CircleCI qqq-orb pipeline where
missing, .editorconfig, .gitattributes, CODEOWNERS, Dependabot, community
pointer files, CHANGELOG, CLAUDE.md/AGENTS.md, docs/DESIGN.md), make the
Maven wrapper executable, and add the README Build/License sections.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 14:43:33 -05:00
james.maesandClaude Opus 5.5 66f6e42ee8 refactor: name permissions web_performance.* per the owner naming rule
Permission base webPerformance -> web_performance (read, write, test,
admin, view). Process and widget names stay webPerformance*.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 14:02:57 -05:00
james.maesandClaude Opus 5.5 7af5ed758e refactor: name tables web_performance_ per the owner naming rule
Owner rule (2026-10-12): table names are lowercase snake_case and every
qbit prefixes its tables with its full name, no abbreviations.

- table prefix webperf_ -> web_performance_ (tables, backend names,
  possible-value sources)
- Liquibase property webperf.tablePrefix -> web_performance.tablePrefix,
  changelog webperf.changelog.sql -> web_performance.changelog.sql
- name prefix and permission base webperf -> webPerformance (processes,
  widgets, process fields, permissions)

Java package and class names unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:55:14 -05:00
james.maesandClaude Opus 5.5 c6a984606c fix: pace CrUX queries under 150 a minute
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:38:41 -05:00
james.maesandClaude Opus 5.5 11b652ae0c feat: P1 lab and field data (PSI/CrUX runners, queue worker, actions, widgets)
- PsiLabRunner (PageSpeed Insights v5, every category, key never in errors)
  and LabResultParser (Lighthouse 13 scores, metrics, LCP element, findings
  keyed by audit id and Lighthouse version, PSI field data)
- CruxClient (CrUX queryRecord; 404 is NO_DATA, stored as such)
- WebPerfService: sitemap sync (nothing deleted), queue with merge and
  daily cap (SKIPPED_QUOTA), worker with conditional claim, retry with
  backoff, findings, gzipped full report, latest page results; CrUX upsert
- standard streamed ETL actions: Test page speed (pages and content
  records), Run site audit, Sync pages from sitemap, Retry, Refresh Google
  field data; hidden scheduled worker, daily key pages, weekly audit,
  daily sync and CrUX
- Performance home widgets (Site Scores, Trend, Slowest Pages, Top
  Opportunities, Google Field Data, Recent Runs) and the record
  Performance panel; readable at every width, real data only
- tests on H2 with the real changelog and a real Lighthouse 13 result of
  www.kof22.com, Google stood in by a local HTTP server

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:37:26 -05:00
james.maesandClaude Opus 5.5 2c18a63a47 feat: qbit-web-performance skeleton (tables, changelog, SPIs, sitemap and build probes)
Local skeleton of the web performance QBit designed in QRun-IO/qqq
docs/specs/2026-10-12-web-performance-design.md (PR #1088; owner decisions
D1-D13 accepted 2026-10-12, D9 amended: alerts via the Alerts qbit).

- WebPerfQBitProducer and WebPerfQBitConfig (validation, namespace prefix,
  duplicate-install guard, Google API key optional and redacted)
- nine visible webperf_ tables, lookups and the Performance app; machine
  tables read-only and unaudited, people-edited tables field-audited
- host-included prefix-parameterized changelog with the seeded budgets
- SPIs: UrlSource, ContentResolver, LabRunner, DeployProbe, RumSource,
  ChangeEventSource
- SitemapUrlSource (XXE-safe, sitemap index) and HttpBuildIdProbe
  (Website-Frontend /api/build)

No PSI/CrUX runner yet: that waits for the Google API key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 12:44:29 -05:00