Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
479 commits
Select commit Hold shift + click to select a range
e1ce135
fix: key the tier merge on org and checkUid so navigation cannot serv…
fclairamb Aug 23, 2026
8481f83
docs: mark useAllResults deprecated and cross-link the TS tier plan w…
fclairamb Aug 23, 2026
51d20f6
chore: all checks passing for Chart queries mix raw and rollup tiers …
fclairamb Aug 23, 2026
84fd525
docs: archive completed spec chart queries mix raw and rollup tiers
fclairamb Aug 23, 2026
06956c9
chore: start implementing Status page response-time fetch scans the w…
fclairamb Aug 23, 2026
9598595
docs: add implementation plan for Status page response-time fetch sca…
fclairamb Aug 23, 2026
35c128a
feat: add a per-check, per-tier recent-results filter that cannot ask…
fclairamb Aug 23, 2026
b0ba937
feat: add RecentResultsPerCheck to both dialects as a per-check, per-…
fclairamb Aug 23, 2026
4d530a4
feat: fetch status-page response times per check and per tier instead…
fclairamb Aug 23, 2026
4e65de3
test: prove the SQLite per-check fetch seeks both partial indexes, wi…
fclairamb Aug 23, 2026
85e257c
test: prove the Postgres per-check LATERAL seeks both partial indexes…
fclairamb Aug 23, 2026
d3bb86f
test: pin point parity, per-check isolation and live raw retention fo…
fclairamb Aug 23, 2026
372587e
fix: satisfy the backend linter and teach the notifications mock the …
fclairamb Aug 23, 2026
9a36fe9
chore: all checks passing for Status page response-time fetch scans t…
fclairamb Aug 23, 2026
e038bae
test: pin the per-check budget rule and the 40k-to-7k row reduction
fclairamb Aug 23, 2026
f638086
chore: all checks passing for Status page response-time fetch scans t…
fclairamb Aug 23, 2026
9805755
test: pin Postgres/SQLite parity for the per-check, per-tier fetch se…
fclairamb Aug 23, 2026
85f4ba0
chore: all checks passing for Status page response-time fetch scans t…
fclairamb Aug 23, 2026
a4fc6e4
docs: archive completed spec status page response time fetch
fclairamb Aug 23, 2026
de11de8
feat: derive status-page cache directives from page visibility
fclairamb Aug 23, 2026
f968257
test: pin who may cache each status-page visibility, and document it
fclairamb Aug 23, 2026
8f65fc6
chore: all checks passing for Public status page view sends no Cache-…
fclairamb Aug 23, 2026
9969536
fix: cache the public incident history by visibility, and stop varyin…
fclairamb Aug 23, 2026
8f8e7fb
chore: all checks passing for Public status page view sends no Cache-…
fclairamb Aug 23, 2026
6b0f4c6
docs: archive completed spec public status page cache control
fclairamb Aug 23, 2026
4374d4f
chore: start implementing Chart loads raw in a second pass over a win…
fclairamb Aug 23, 2026
547b3bb
docs: add implementation plan for Chart loads raw in a second pass ov…
fclairamb Aug 23, 2026
8325a19
feat: clamp raw-tier result queries to the retention band and report …
fclairamb Aug 23, 2026
7715e72
test: pin the raw-tier clamp, its retention source, and the window it…
fclairamb Aug 23, 2026
5f93737
feat: load the chart's raw tier in a second pass over the rollup seam
fclairamb Aug 23, 2026
43a551c
test: pin the seam window, the progressive render and the polling scope
fclairamb Aug 23, 2026
c20779a
refactor: extract the results list filter builder out of ListResults
fclairamb Aug 23, 2026
3bb4f23
chore: all checks passing for Chart loads raw in a second pass over a…
fclairamb Aug 23, 2026
99237db
fix: anchor the seam on the bucket edge and resolve the chart window …
fclairamb Aug 23, 2026
a2366a3
chore: all checks passing for Chart loads raw in a second pass over a…
fclairamb Aug 23, 2026
9651e8d
docs: archive completed spec chart loads raw in a second pass
fclairamb Aug 23, 2026
4b9f99e
fix: add uid DESC tie-break for same-period_start rollup points
fclairamb Aug 23, 2026
7f34707
chore: all checks passing for Two rollup points sharing a period_star…
fclairamb Aug 23, 2026
b166da6
docs: archive completed spec response time tie break determinism
fclairamb Aug 23, 2026
e36f0ee
fix: keep pointer-valued fields in audit payloads instead of dropping…
fclairamb Aug 23, 2026
92628d2
fix: stop 500ing on the 100th auto-slugged check for one host
fclairamb Aug 23, 2026
fb0c9d5
fix: stop the login page unmounting mid-org-picker redirect
fclairamb Aug 23, 2026
448110c
test: read the public status page past its own 60 s cache directive
fclairamb Aug 23, 2026
87dff7e
chore: satisfy varnamelen and govet in the audit pointer unwrap
fclairamb Aug 23, 2026
7432e85
chore: all E2E specs passing on batch/2026-08-21
fclairamb Aug 23, 2026
52311a1
fix: serve the API reference index at /docs/api
fclairamb Aug 23, 2026
6c6c04b
docs: group the migration guides under a Migration menu
fclairamb Aug 23, 2026
8790daa
docs: nest the migration guides under /features/migrate
fclairamb Aug 23, 2026
626f641
docs: recommend migrating with an AI agent over the MCP server
fclairamb Aug 23, 2026
b6b211f
chore: default the seeded admin to admin@solidping.io
fclairamb Aug 23, 2026
4df5f61
docs(specs): custom-domain demotion, and the seeded superadmin
fclairamb Aug 23, 2026
ada0bae
chore(deps): merge github-actions updates (Go 1.27, golangci-lint v2.…
fclairamb Aug 23, 2026
7b19ac0
Merge remote-tracking branch 'origin/main' into batch/2026-08-21
fclairamb Aug 23, 2026
dbbe08e
chore: keep the unparam waiver on the MongoDB ping helper
fclairamb Aug 23, 2026
b4293d0
docs: resolve open questions for the seeded default admin spec
fclairamb Aug 23, 2026
49d4038
docs: resolve open questions for the custom-domain demotion spec
fclairamb Aug 23, 2026
18dff67
docs: raise model/effort on the two specs the resolutions enlarged
fclairamb Aug 23, 2026
c977a35
fix(config): slugify hostname-derived worker slug instead of refusing it
fclairamb Aug 23, 2026
d26f09d
test(config): cover hostname sanitization for the derived worker slug
fclairamb Aug 23, 2026
b3ed91f
test(jobworker): tolerate the sanitization WARN in the real-hostname …
fclairamb Aug 23, 2026
966d450
chore: all checks passing for Slugify hostname-derived worker slug
fclairamb Aug 23, 2026
2b5563f
fix(config): make the fixed-point property hold by construction
fclairamb Aug 23, 2026
1ee1968
chore: all checks passing for Slugify hostname-derived worker slug
fclairamb Aug 23, 2026
66b1722
docs: archive completed spec Slugify hostname-derived worker slug
fclairamb Aug 23, 2026
e223ba3
chore: start implementing Custom-domain demotion recovery and legible…
fclairamb Aug 23, 2026
1529b72
docs: add implementation plan for Custom-domain demotion recovery and…
fclairamb Aug 23, 2026
39d5b29
feat(custom-domain): explicit lifecycle state, stored-cert handshake,…
fclairamb Aug 23, 2026
94ff74f
feat(custom-domain): grace/re-promotion sweep, demotion alert, DNS di…
fclairamb Aug 23, 2026
a1bffd6
test(custom-domain): cover grace, re-promotion, legible TLS failure a…
fclairamb Aug 23, 2026
89b3d47
feat(dash0): surface the custom-domain grace state and its DNS diagno…
fclairamb Aug 23, 2026
95f88df
docs(specs): file the residual custom-domain verification investigation
fclairamb Aug 23, 2026
f94ad86
fix(custom-domain): classify the demotion email and clear lint findings
fclairamb Aug 23, 2026
9ffa993
chore: all checks passing for Custom-domain demotion recovery and leg…
fclairamb Aug 23, 2026
1960c51
feat(custom-domain): alert on a hard demotion reached through Verify too
fclairamb Aug 23, 2026
5622469
chore: all checks passing for Custom-domain demotion recovery and leg…
fclairamb Aug 23, 2026
bd9a297
docs: archive completed spec Custom-domain demotion recovery and legi…
fclairamb Aug 23, 2026
2f10e88
chore: start implementing Forced rotation for the seeded default admin
fclairamb Aug 23, 2026
3ecc0db
docs: add implementation plan for Forced rotation for the seeded defa…
fclairamb Aug 23, 2026
0480dbd
feat(auth): force a password rotation on flagged accounts
fclairamb Aug 23, 2026
2225fa6
feat(dash0): add the forced password-rotation screen
fclairamb Aug 23, 2026
73d6d4e
docs: note the forced rotation on the seeded admin's first login
fclairamb Aug 23, 2026
e434c44
test(auth): prove the forced-rotation gate blocks, allows and lifts
fclairamb Aug 23, 2026
1b9780c
docs: reconcile the implementation plan with where the signal landed
fclairamb Aug 23, 2026
c2ba78c
chore: all checks passing for Forced rotation for the seeded default …
fclairamb Aug 23, 2026
d9692ed
test(cli): cover the login-time forced-rotation notice
fclairamb Aug 23, 2026
0abbe48
chore: all checks passing for Forced rotation for the seeded default …
fclairamb Aug 23, 2026
13a7ca3
fix(dash0): label the custom-domain demotion event in every locale
fclairamb Aug 23, 2026
4943a64
docs: archive completed spec Forced rotation for the seeded default a…
fclairamb Aug 23, 2026
42bf8de
docs: resolve open questions for A removed custom domain still fails …
fclairamb Aug 23, 2026
4874e14
docs: resolve open questions for Two unauthenticated test-only routes…
fclairamb Aug 23, 2026
f740a31
docs: record the custom-domain re-verification investigation (resolve…
fclairamb Aug 23, 2026
93a081c
docs(domainverify): correct what LookupCNAME returns for a chained ta…
fclairamb Aug 23, 2026
82bc5ca
chore: all checks passing for Custom-domain re-verification fails whi…
fclairamb Aug 23, 2026
7073cb0
docs: archive completed spec Custom-domain re-verification fails whil…
fclairamb Aug 23, 2026
d85b428
docs: close spec A removed custom domain still fails at the TLS hands…
fclairamb Aug 23, 2026
0f38c5a
fix(server): gate /test/jobs on RunMode=test and bound the public /fa…
fclairamb Aug 23, 2026
bcebf5f
test(server): cover the RunMode=test gate and the /fake delay ceiling…
fclairamb Aug 23, 2026
ff8d11c
chore: all checks passing for Two unauthenticated test-only routes ar…
fclairamb Aug 23, 2026
6ba95c5
docs: archive completed spec Two unauthenticated test-only routes are…
fclairamb Aug 23, 2026
de8c303
fix(lint): drop the unused unparam waiver on the MongoDB ping helper
fclairamb Aug 23, 2026
2b14759
fix(lint): name the TLS-storage prefix fixture's lists to break a for…
fclairamb Aug 23, 2026
2d42403
fix(notifications): make browser push notifications incident-aware
fclairamb Aug 23, 2026
109a6cc
fix(agentws): subscribe to check.created before announcing the connec…
fclairamb Aug 23, 2026
e2ccabb
refactor(db): consolidate the four unreleased v0.18.0 migrations into…
fclairamb Aug 23, 2026
f896332
docs: resolve open questions for Incident acknowledgment shows no act…
fclairamb Aug 23, 2026
e83ca0d
fix: address escalation Slack DMs by check name and #N, with an incid…
fclairamb Aug 23, 2026
6ffda41
chore: all checks passing for The escalation Slack DM addresses the i…
fclairamb Aug 23, 2026
cee76e8
docs: archive completed spec The escalation Slack DM addresses the in…
fclairamb Aug 23, 2026
7d2a91e
chore: start implementing Incident acknowledgment shows no actor in t…
fclairamb Aug 23, 2026
8a216bb
docs: add implementation plan for Incident acknowledgment shows no ac…
fclairamb Aug 23, 2026
1f6334a
feat: resolve and expose the incident acknowledgment actor
fclairamb Aug 23, 2026
c906e9b
feat: notify every paged channel when an incident is acknowledged
fclairamb Aug 23, 2026
9ab756d
feat: tell the people paged over telegram that an incident was acknow…
fclairamb Aug 24, 2026
279564b
feat: show who acknowledged an incident in the dashboard
fclairamb Aug 24, 2026
759e334
test: cover ack attribution, notice fan-out and per-channel rendering
fclairamb Aug 24, 2026
18ceb34
fix(lint): satisfy contextcheck, goconst, cyclop and exhaustive on th…
fclairamb Aug 24, 2026
c94f021
test(e2e): pin the acknowledgment attribution on the incident detail …
fclairamb Aug 24, 2026
aeb1dde
feat: name the acker in the organization events feed too
fclairamb Aug 24, 2026
d934550
chore: all checks passing for Incident acknowledgment shows no actor …
fclairamb Aug 24, 2026
c7d22eb
docs: archive completed spec Incident acknowledgment shows no actor i…
fclairamb Aug 24, 2026
caeb2b8
fix(auth): capture request provenance on every session-minting path
fclairamb Aug 24, 2026
14d3c28
test(auth): cover created_with provenance across every session-mintin…
fclairamb Aug 24, 2026
81d1485
feat(dash0): label every auth method a session can carry, not just three
fclairamb Aug 24, 2026
be5c3c6
test(e2e): pin the sessions page's device label off Unknown device
fclairamb Aug 24, 2026
ce990f9
chore: all checks passing for Federated (OAuth/SSO) sessions are stor…
fclairamb Aug 24, 2026
9bcc719
docs: archive completed spec Federated (OAuth/SSO) sessions are store…
fclairamb Aug 24, 2026
7bb4758
feat(dash0): add check filter to the incidents list
fclairamb Aug 24, 2026
6959224
test(e2e): cover the incidents check filter
fclairamb Aug 24, 2026
4dca72c
fix(dash0): carry the new checkUid search param through every inciden…
fclairamb Aug 24, 2026
82c5777
fix(e2e): resolve a strict-mode locator collision in the empty check-…
fclairamb Aug 24, 2026
c7c2516
chore: all checks passing for The incidents list can't be narrowed to…
fclairamb Aug 24, 2026
410c627
docs: archive completed spec The incidents list can't be narrowed to …
fclairamb Aug 24, 2026
d850096
chore: start implementing The checks list can't filter on Validating,…
fclairamb Aug 24, 2026
0904b0c
docs: add implementation plan for The checks list can't filter on Val…
fclairamb Aug 24, 2026
d4803e7
feat(backend): accept validating in the checks status filter
fclairamb Aug 24, 2026
6f2ca1a
feat(dash0): faceted status and type filters on the checks list
fclairamb Aug 24, 2026
5d03acb
docs(dash0): add the FacetedFilter primitive to the design reference
fclairamb Aug 24, 2026
8668593
test(testdata): seed a deterministic validating check for test mode
fclairamb Aug 24, 2026
2ef2e55
test(e2e): cover the checks-list status and type faceted filters
fclairamb Aug 24, 2026
b168551
chore: all checks passing for The checks list can't filter on Validat…
fclairamb Aug 24, 2026
7f24a68
fix(dash0): unify the ssl check type's label as TLS across surfaces
fclairamb Aug 24, 2026
84a5b05
chore: all checks passing for The checks list can't filter on Validat…
fclairamb Aug 24, 2026
3befc70
docs: archive completed spec The checks list can't filter on Validati…
fclairamb Aug 24, 2026
d6b651c
chore: start implementing Flap state is invisible and the reopen cool…
fclairamb Aug 24, 2026
f7164c9
docs: add implementation plan for Flap state is invisible and the reo…
fclairamb Aug 24, 2026
cf2d21e
refactor(incidents): lift effective-recovery-period math onto models.…
fclairamb Aug 24, 2026
20f6952
feat(incidents): record and expose flap_level on create and reopen
fclairamb Aug 24, 2026
636b810
feat(db): add incidents.flap_level to the v0.18.0 consolidated migration
fclairamb Aug 24, 2026
869be75
feat(checks): expose live flapState on CheckResponse
fclairamb Aug 24, 2026
bf16434
docs(openapi): document flapState on Check and flapLevel on IncidentD…
fclairamb Aug 24, 2026
7783b4f
test(flapping): cover EffectiveFlapCount, flapState presence, and fla…
fclairamb Aug 24, 2026
f90be2d
feat(dash0): add flapState/flapLevel to the Check and Incident API types
fclairamb Aug 24, 2026
c779125
feat(dash0): show the flapping state on the check detail page
fclairamb Aug 24, 2026
7d53117
feat(dash0): add a 'flapping ×N' badge on the incidents list and detail
fclairamb Aug 24, 2026
49795ed
feat(dash0): show the actual reopen-cooldown window, and shorten the …
fclairamb Aug 24, 2026
58d3f9a
test(dash0): cover the reopen-cooldown clamp hint and its rendering i…
fclairamb Aug 24, 2026
2d9d97d
chore: all checks passing for Flap state is invisible and the reopen …
fclairamb Aug 24, 2026
f5aee47
refactor(dash0): extract flappingSummaryParams to a tested lib module
fclairamb Aug 24, 2026
6ca0904
chore: all checks passing for Flap state is invisible and the reopen …
fclairamb Aug 24, 2026
fa84e4b
refactor(dash0): extract the flapping badge into a shared component, …
fclairamb Aug 24, 2026
0d0093f
chore: all checks passing for Flap state is invisible and the reopen …
fclairamb Aug 24, 2026
8113d95
docs: archive completed spec Flap state is invisible and the reopen c…
fclairamb Aug 24, 2026
78516f0
docs: add status badges, discovery, and events feature pages
fclairamb Aug 24, 2026
008735e
feat(dash0): wire docsHref on SLOs, badges, discovery, events, and de…
fclairamb Aug 24, 2026
9f284ac
test(dash0): assert docs-link href on all five newly-wired pages
fclairamb Aug 24, 2026
8d5c60a
chore: all checks passing for SLOs, badges, discovery, events and dep…
fclairamb Aug 24, 2026
789d300
docs: fix inaccuracies found in the discovery/events/badges pages audit
fclairamb Aug 24, 2026
3051435
chore: all checks passing for SLOs, badges, discovery, events and dep…
fclairamb Aug 24, 2026
0c23956
docs: archive completed spec SLOs, badges, discovery, events and depe…
fclairamb Aug 24, 2026
4811c22
docs(specs): region migration API, ghost-region detection, platform w…
fclairamb Aug 24, 2026
819e1d6
fix(e2e): stop the incidents check-filter test depending on list page 1
fclairamb Aug 24, 2026
5435294
Merge remote-tracking branch 'origin/main' into batch/2026-08-21
fclairamb Aug 24, 2026
cd5e68f
docs: resolve open questions for group incidents read-time aggregation
fclairamb Aug 24, 2026
8763f6e
docs(dash0): decide onboarding quick-start keeps SSL, not TLS
fclairamb Aug 24, 2026
98764d2
chore: all checks passing for The dashboard onboarding quick-start ch…
fclairamb Aug 24, 2026
7dd56bb
docs: archive completed spec The dashboard onboarding quick-start chi…
fclairamb Aug 24, 2026
1c898c2
chore: start implementing Renaming a region strands its check_jobs fo…
fclairamb Aug 24, 2026
e93b6d3
docs: add implementation plan for region migration API
fclairamb Aug 24, 2026
4dc53b7
feat(regions): add server-scope region migration API and stale-region…
fclairamb Aug 24, 2026
1af49b0
docs(openapi): document POST /system/regions/migrate
fclairamb Aug 24, 2026
91a2e43
test(regions): cover region migration and stale-region startup reconcile
fclairamb Aug 24, 2026
f24879a
chore(regions): satisfy lint on the region migration code paths
fclairamb Aug 24, 2026
e928a34
docs(server): the startup reconcile now heals region drift too
fclairamb Aug 24, 2026
c52328d
chore: all checks passing for Renaming a region strands its check_job…
fclairamb Aug 24, 2026
2f918d6
docs: archive completed spec Renaming a region strands its check_jobs…
fclairamb Aug 24, 2026
75b1d4c
chore: start implementing Ghost regions are invisible — one API call …
fclairamb Aug 24, 2026
6509579
docs: add implementation plan for ghost region detection API
fclairamb Aug 24, 2026
b42cf65
feat(regions): add ghost-region detection service and GET /system/reg…
fclairamb Aug 24, 2026
17e8b76
docs(openapi): document GET /system/regions/health
fclairamb Aug 24, 2026
7c69f9b
test(regions): cover ghost-region detection, liveness boundary, and a…
fclairamb Aug 24, 2026
d5deaee
test(regions): add embedded-Postgres twin for the checks.regions arra…
fclairamb Aug 24, 2026
b4b8536
chore: all checks passing for Ghost regions are invisible — one API c…
fclairamb Aug 24, 2026
516a713
fix(regions): pin RegionHealth's clock via an injectable now() for ex…
fclairamb Aug 24, 2026
37e692d
chore: all checks passing for Ghost regions are invisible — one API c…
fclairamb Aug 24, 2026
e36f40c
docs: archive completed spec Ghost regions are invisible — one API ca…
fclairamb Aug 24, 2026
e5db6bc
chore: start implementing The monitoring system cannot tell anyone it…
fclairamb Aug 24, 2026
3c9ad4d
docs: add implementation plan for internal anomaly watchdog
fclairamb Aug 24, 2026
d3910eb
feat(watchdog): add the platform self-monitoring detector package
fclairamb Aug 24, 2026
1b8e6f9
feat(watchdog): export per-detector anomaly gauges through prommetrics
fclairamb Aug 24, 2026
3867db5
feat(watchdog): add the hourly platform-watchdog job, delivery and pa…
fclairamb Aug 24, 2026
89d3e1a
test(watchdog): cover the three detectors, the transition ladder and …
fclairamb Aug 24, 2026
8fffb1a
test(watchdog): cover delivery, undeliverable recipients and the disa…
fclairamb Aug 24, 2026
bffc441
docs(wiki): document the platform watchdog; test detector panic conta…
fclairamb Aug 24, 2026
f2ef042
chore: all checks passing for The monitoring system cannot tell anyon…
fclairamb Aug 24, 2026
0b5fef6
fix(watchdog): reschedule from a defer and dedupe recipients by conta…
fclairamb Aug 24, 2026
4ad2cd1
chore: all checks passing for The monitoring system cannot tell anyon…
fclairamb Aug 24, 2026
a1c96ee
docs: archive completed spec The monitoring system cannot tell anyone…
fclairamb Aug 24, 2026
146fedf
feat(dash0): render inline incident timestamps in local time, UTC on …
fclairamb Aug 24, 2026
8195d40
test(dash0): cover local-first formatInlineAbsolute, pin TZ for deter…
fclairamb Aug 24, 2026
db37be4
test(e2e): pin non-UTC timezone for the incident timeline inline variant
fclairamb Aug 24, 2026
29e8048
chore: all checks passing for The incident timeline shows UTC inline;…
fclairamb Aug 24, 2026
5792ff6
docs: archive completed spec The incident timeline shows UTC inline; …
fclairamb Aug 24, 2026
f5d8143
fix(dash0): render a literal em dash for empty check duration
fclairamb Aug 24, 2026
aa82ced
test(e2e): assert the checks list duration cell renders a literal em …
fclairamb Aug 24, 2026
c3a97cb
chore: all checks passing for Checks list shows the literal text — in…
fclairamb Aug 24, 2026
eb456cc
docs: archive completed spec Checks list shows the literal text — ins…
fclairamb Aug 24, 2026
ef84737
feat(server): report invitation email delivery status, fix hardcoded …
fclairamb Aug 24, 2026
3ea6bc6
test(server): cover invitation email delivery status and real expiry
fclairamb Aug 24, 2026
d43ed95
feat(dash0): lead invitation success state with the email, link as fa…
fclairamb Aug 24, 2026
986f96d
revert(server): drop client_generated.go regen from the invitations spec
fclairamb Aug 24, 2026
1357ab7
chore: all checks passing for Invitations should be email-first: send…
fclairamb Aug 24, 2026
cf5bc3e
docs: archive completed spec Invitations should be email-first: send …
fclairamb Aug 24, 2026
dfa5a8e
chore: start implementing Group incidents hide member failures and de…
fclairamb Aug 24, 2026
6f5e5f2
docs: add implementation plan for per-check incidents with read-time …
fclairamb Aug 24, 2026
cfd7079
refactor(server): delete the group-incident creation path
fclairamb Aug 24, 2026
11beb08
feat(db): close active group incidents and stop member-row incident b…
fclairamb Aug 24, 2026
7317bd1
feat(statuspages): consolidate group members into one public entry
fclairamb Aug 24, 2026
4d09018
test(incidents): pin per-check incidents for grouped checks
fclairamb Aug 24, 2026
8f4ccee
feat(dash0): group active incidents by check group at read time
fclairamb Aug 24, 2026
d34569a
test(e2e): pin the incidents-list check-group header
fclairamb Aug 24, 2026
13e96b1
refactor(db): drop the now-unreachable group-incident finders
fclairamb Aug 24, 2026
05e1372
chore: all checks passing for Group incidents hide member failures an…
fclairamb Aug 24, 2026
5396ea1
docs(wiki): architecture.md described group incidents as a live mecha…
fclairamb Aug 24, 2026
de19076
docs: archive completed spec Group incidents hide member failures and…
fclairamb Aug 24, 2026
33562c9
chore: start implementing Dependency rollup misses the common case wh…
fclairamb Aug 24, 2026
e26be01
docs: add implementation plan for late-arriving-parent rollup re-eval…
fclairamb Aug 24, 2026
1cddcb2
feat(incidents): re-evaluate hard children when a parent incident opens
fclairamb Aug 24, 2026
82832c9
test(incidents): pin the late-arriving-parent rollup in both directions
fclairamb Aug 24, 2026
701d814
chore: all checks passing for Dependency rollup misses the common cas…
fclairamb Aug 24, 2026
107812f
docs: archive completed spec Dependency rollup misses the common case…
fclairamb Aug 24, 2026
669648d
chore: start implementing Discord login fails permanently with "sql: …
fclairamb Aug 24, 2026
92f0e7f
docs: add implementation plan for Discord stale guild link login failure
fclairamb Aug 24, 2026
7570337
feat(auth): self-heal stale organization/user provider links on SSO l…
fclairamb Aug 24, 2026
58700b0
fix(dash0): strip OAuth error params before reusing the URL as redire…
fclairamb Aug 24, 2026
abb39a4
test(auth): pin stale provider-link healing on SQLite and Postgres
fclairamb Aug 24, 2026
e4af6a3
chore: all checks passing for Discord stale guild link login failure
fclairamb Aug 24, 2026
09f0136
chore: all checks passing for Discord stale guild link login failure
fclairamb Aug 24, 2026
e1fc43f
docs: archive completed spec Discord login fails permanently when the…
fclairamb Aug 24, 2026
d8fea2d
feat(dash0): put the audit cursor in the URL and surface docs links
fclairamb Aug 24, 2026
aac19cc
docs(changelog): add unreleased entries for the Discord bot, audit lo…
fclairamb Aug 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 11 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,14 @@ SP_TELEGRAM_BASE_URL=
# there is deliberately no monthly quota — this only bounds a flapping check
# or a broken dispatch loop.
SP_ENTITLEMENTS_TELEGRAM_RUNAWAY_PER_HOUR=

# ---------------------------------------------------------------------------
# Frontend dev server (web/dash0)
# ---------------------------------------------------------------------------

# Extra hostnames the Vite dev server will answer for, comma-separated. Only
# needed when you reach `make dev` through a tunnel or a remote hostname rather
# than localhost — Vite rejects unknown Host headers otherwise. Empty = only
# localhost, which is what most people want.
# VITE_DEV_ALLOWED_HOSTS=app.dev.example.com
VITE_DEV_ALLOWED_HOSTS=
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:

- uses: actions/setup-go@v7
with:
go-version: "1.26"
go-version: "1.27"
cache-dependency-path: server/go.sum

- name: Create embed placeholders for lint/test
Expand Down Expand Up @@ -76,7 +76,7 @@ jobs:
uses: golangci/golangci-lint-action@v9.3.0
with:
# https://github.com/golangci/golangci-lint/releases
version: v2.12.2
version: v2.13.1
install-mode: goinstall
working-directory: server
# only-new-issues: true
Expand Down Expand Up @@ -237,7 +237,7 @@ jobs:

- uses: actions/setup-go@v7
with:
go-version: "1.26"
go-version: "1.27"
cache-dependency-path: server/go.sum

- name: Download dash dist
Expand Down
40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,45 @@
# Changelog

## [Unreleased]


### Features

* **discord:** a first-class Discord bot, not just a webhook. Install it into a server, map servers to organizations, and get incidents as bot-owned threads that edit in place and carry acknowledge and comment buttons. Org members map to Discord identities so on-call mentions reach the right person, comments posted in the thread are ingested back onto the incident through a Gateway supervisor, slash-command and mention dispatch is transport-agnostic, and every inbound interaction is Ed25519-verified with stale and unsigned requests rejected. Ships with a bot settings panel and a server-admin page in the dashboard
* **audit:** an organization audit log. Every session-minting path, membership change, token operation, config apply, and escalation / on-call / maintenance / integration / status-page mutation emits a typed event carrying actor metadata and a normalized source address. Payload redaction fails closed on anything it does not recognize, failed logins are flood-controlled, and retention is swept by a cleanup job. The events API gained family, type, actor, target and admin-only IP filters plus working cursors; the dashboard gained an admin-gated audit page; and every event family has a human identity in all four locales
* **slo:** burn-rate alerting on SLOs. Define an alert policy over an SLO and get paged when the error budget burns too fast, evaluated over multiple windows against a shared evaluator. Burn incidents are a distinct incident kind rather than a check failure, with their own lifecycle entry points, their own email and Slack templates, and a periodic sweep job. The dashboard gained an SLO alerting section, a burning badge and a policy edit route
* **diagnostics:** MTR-style path tracing on network failures. A pure-Go path prober with a privilege ladder traces the route when a network-reachability failure opens an incident, so the incident shows where the packets actually stopped. Exposed as an org-level default plus a per-check policy, rendered on the incident and on the onset result page, and pinned never-public
* **support:** a support inbox. Inbound human messages are captured from email, WhatsApp, Telegram, SMS, Slack DMs and Discord DMs into threads and messages, with idempotent capture, abuse ceilings and a mailbox mirror. Replies go back out through per-provider adapters and take their delivery status from the existing provider callbacks, and instance support Reply-To is classified fail-closed per template. Ships with a retention job, org-deletion detach, an OpenAPI-documented API and a `/support` inbox in the dashboard
* **email:** the JMAP inbox consumer is safe to run more than once — inbound mail is deduplicated by `Message-ID` before insert, claimed by archiving it before processing, and the consumer runs under a Postgres advisory lock
* **status-pages:** branding and private pages. Upload a per-page logo and favicon (gated by a white-label entitlement), password-protect a page behind an unlock cookie, and let visitors subscribe over webhook or Slack. Branding moved into settings, and public assets are authorized by file topic
* **incidents:** screenshots of what the browser saw. Browser checks can opt into capturing a screenshot on failure, persisted when the incident opens and rendered in the dashboard. Built on a new generic attachment rail (`files.topic` / `files.details`) with an agent upload endpoint, an out-of-band upload frame, a bounded TTL'd capture LRU for deported agents, orphan reaping, and attachments pinned out of public payloads
* **incidents:** acknowledgement now has a face. The acknowledging actor is resolved and exposed, every paged channel is notified that the incident was acknowledged (Telegram included), and the dashboard and the organization events feed both name who acknowledged it
* **incidents:** flapping is visible. `flap_level` is recorded and exposed on create and reopen, checks carry a live `flapState`, and the dashboard shows a flapping state on check detail plus a "flapping ×N" badge on the incidents list and detail, alongside the actual reopen-cooldown window
* **incidents:** check groups are handled as groups. Active group incidents are closed and member-row incident binding stopped, status pages consolidate group members into a single public entry, the dashboard groups active incidents by check group at read time, and hard children are re-evaluated when a parent incident opens
* **custom-domain:** an explicit custom-domain lifecycle — a stored-cert handshake, a legible 503 while the domain is not ready, a grace and re-promotion sweep, a demotion alert (including demotions reached through Verify), and DNS diagnostics surfaced in the dashboard
* **regions:** a server-scope region migration API with stale-region reconciliation at startup, plus ghost-region detection behind `GET /system/regions/health`
* **watchdog:** the platform monitors itself. A detector package feeds per-detector anomaly gauges through Prometheus, driven by an hourly platform-watchdog job with delivery and parameter validation
* **auth:** flagged accounts are forced through a password rotation, with a dedicated rotation screen in the dashboard
* **auth:** stale SSO provider links heal themselves. A soft-deleted organization used to leave its Discord guild or Slack team link alive, which permanently bricked login for everyone in that guild — the stale link is now cleared and re-linked on the next sign-in, and the same fallback covers user links across all nine connectors
* **import:** UptimeRobot as an import source, with a golden-tested converter and a dashboard source picker
* **performance:** result and chart queries seek instead of scan. Result blobs are skipped when unrequested, the keyset cursor seeks by row value, the chart fetch is split at the raw/rollup boundary into parallel tier queries (and still seeks on SQLite), a per-check per-tier recent-results filter cannot ask for a mixed tier, status-page response times are fetched per check and per tier instead of scanning results, raw-tier queries are clamped to the retention band and report the effective window, and status-page cache directives derive from page visibility
* **dash0:** faceted status and type filters on the checks list, a check filter on the incidents list, documentation links across SLOs, badges, discovery, events and dependencies, incident timestamps rendered in local time with UTC on hover, invitation email delivery status led by the address with the link as fallback, and every auth method a session can carry is labelled


### Bug Fixes

* **audit:** every session-minting path is recorded, not just password logins; redaction fails closed on unrecognized payload value types and keeps pointer-valued fields; the events cursor gained a uid tie-break; the OAuth grant path is audited and the guard widened past the auth package; and an OAuth grant presented by the wrong client is recorded as token misuse
* **traceroute:** an HTTP response stall is no longer labelled a connect timeout, the connection phase resets at dial start so a redirect chain keeps a real connect timeout, a panic on either trace goroutine is recovered, the per-check policy survives export, import and clone, and an agent-uploaded capture is stamped with the probing region
* **support:** `SP_SUPPORT_RETENTION_DAYS=0` genuinely means keep forever, an abuse-ceiling drop counts as throttled rather than failed, and the re-scan path fails closed with the dedup lookup scoped to the org index
* **charts:** the tier merge is keyed on org and check so navigation cannot serve stale rows, the seam is anchored on the bucket edge with the chart window resolved once, and same-`period_start` rollup points get a uid DESC tie-break
* **status-pages:** public incident history is cached by visibility, and public pages no longer vary on `Cookie`
* **notifications:** browser push notifications are incident-aware, escalation Slack DMs address the check by name and number with an incident link, and the agent websocket subscribes to `check.created` before announcing the connection
* **checks:** the 100th auto-slugged check for one host no longer 500s, and `validating` is accepted in the status filter
* **db:** generic attachments moved out of the already-released migration 014 into a new 015
* **config:** a hostname-derived worker slug is slugified instead of refused, and the fixed-point property holds by construction
* **dash0:** the login page no longer unmounts mid-org-picker redirect, `apiFetch` tolerates an empty body under any status rather than only 204, breadcrumb leaves resolve for every Organization tab and deep route, the SSL check type is labelled TLS across all surfaces, and an empty check duration renders a literal em dash
* **docs:** the API reference index is served at `/docs/api`

## [0.17.0](https://github.com/fclairamb/solidping/compare/v0.16.2...v0.17.0) (2026-08-20)


Expand Down
17 changes: 15 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,22 @@ Dev logs live in `logs/*.log` (`backend.log`, `dash0.log`, `status0.log`), size-

| Mode | Email | Password | Org |
|---|---|---|---|
| Normal | `admin@solidping.com` | `solidpass` | `default` |
| Normal | `admin@solidping.io` | `solidpass` | `default` |
| Test (`SP_RUNMODE=test`) | `test@test.com` | `test` | `test` |

**The normal seeded admin lands on a forced password rotation.** On a fresh
database the seeded `admin@solidping.io` carries `users.must_change_password`,
so the first successful login yields a session that can reach only
`POST /auth/change-password`, `GET /auth/me` and `POST /auth/logout` —
everything else answers `403 PASSWORD_CHANGE_REQUIRED` and dash0 lands on
`/dash0/change-password`. This is unconditional: `make dev` against a fresh
database prompts for a new password too. Pick one, and every example below
works with it in place of `solidpass`.

The test-mode user (`test@test.com`) is deliberately **not** flagged — it is
created by a different path (`server/test/testdata/testdata.go`) and the
Playwright suites sign in with those fixed credentials.

## SaaS mode & entitlements

`SP_DEPLOYMENT_MODE=saas` switches per-org defaults to the SaaS tier and lets a
Expand Down Expand Up @@ -126,7 +139,7 @@ Key codes: `INTERNAL_ERROR`, `VALIDATION_ERROR`, `NOT_FOUND`, `UNAUTHORIZED`, `F
### Quick API test
```bash
TOKEN=$(curl -s -X POST -H 'Content-Type: application/json' \
-d '{"org":"default","email":"admin@solidping.com","password":"solidpass"}' \
-d '{"org":"default","email":"admin@solidping.io","password":"solidpass"}' \
'http://localhost:4000/api/v1/auth/login' | jq -r '.accessToken')
curl -s -H "Authorization: Bearer $TOKEN" 'http://localhost:4000/api/v1/orgs/default/checks'
```
Expand Down
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,22 @@ make dev-test # Backend + frontend with hot reload
```

### Default Credentials
- Email: `admin@solidping.com`
- Email: `admin@solidping.io`
- Password: `solidpass`
- Organization: `default`

Both halves of that pair are published here, so the first login on a fresh
database **must set a new password** before the account can do anything else.
The dashboard takes you straight to the form; over the API the login succeeds
and every endpoint except `POST /api/v1/auth/change-password`,
`GET /api/v1/auth/me` and `POST /api/v1/auth/logout` answers `403` with code
`PASSWORD_CHANGE_REQUIRED` until you rotate it.

### API Example
```bash
# Get a JWT token
TOKEN=$(curl -s -X POST -H 'Content-Type: application/json' \
-d '{"org":"default","email":"admin@solidping.com","password":"solidpass"}' \
-d '{"org":"default","email":"admin@solidping.io","password":"solidpass"}' \
'http://localhost:4000/api/v1/auth/login' | jq -r '.accessToken')

# List checks
Expand Down
41 changes: 0 additions & 41 deletions deploy/docs-ingress.yaml

This file was deleted.

Loading
Loading