Skip to content
changelog

What shipped, and when.

Dated from the commit history, not written for the website. Parsemend's history starts on the day the ingest pipeline first accepted an event from an unmodified Sentry SDK, which is why the earliest entries share a date.

added

Autonomous QA: flows, failures as issues, and a CI gate

Natural-language browser flows replay deterministically with zero steady-state model calls. A failing flow files a correlated issue, the parsemend/qa check links it, and qa:verify-fix closes the loop.

A flow is a natural-language browser journey (ordered steps and assertions) that a model resolves to a locator stack once per flow, step and environment, then caches. After that, replays are deterministic Chromium runs through a separate runner package with zero LLM calls; the cache heals on locator drift and never rescues a failing assertion.

A failed run now files a first-class issue through the same pipeline as an exception: alerts, fixability scan and regression semantics apply. A triage agent annotates the issue app_bug, flow_outdated, environment or unknown, but never decides pass or fail; the raw run result does, and a flaky failure gets a retry before it counts. Runs correlate against server-side errors in the same time window.

The parsemend/qa GitHub check links each failed flow to its filed issue. The CLI (parsemend qa run --wait --json, qa export) exits with the raw pass/fail code for scripting, and deploy-triggered suite runs put QA in the path of a release. qa:verify-fix re-runs a failing flow against a fix PR's preview URL. A pass there never resolves the canonical issue; only a deploy or scheduled run does.

added

Metric and anomaly alerts, and a per-project Health page

Threshold, percent-change and anomaly rules over fixed per-project rollups. A breach files a synthetic issue; a new Health page tracks error count, failure rate and p95.

Alert rules can now fire on aggregate behaviour, not only on individual issues: a static threshold, a percent-change against the prior window, or an anomaly rule (rolling mean ± k·stddev; plain statistics, no ML) over per-project, per-environment rollups of error count, distinct-issue count, transaction failure rate and p95 duration.

A breach files a synthetic issue through the same email, Slack and webhook actions, cooldown and audit trail as any other alert, and enough consecutive clean rollups auto-resolve it. Crash-free rate is not one of the rollups; that needs session ingestion, which Parsemend does not do.

Each project also gets a Health page for the last 24 hours and 7 days: error count with a trend sparkline, plus failure rate and p95 duration as point figures, read from the same fixed rollups.

added

Dependency and secret scanning on pull requests

Lockfile diffs checked against OSV and Packagist advisories, typosquat and tamper heuristics, and added-lines-only secret scanning. A daily sweep opens issues for advisories on packages you already run.

Every reviewed PR now inspects lockfile and manifest diffs (composer.lock, package-lock v1 to v3, Yarn classic and Berry, pnpm) against OSV.dev and Packagist advisories, plus heuristics for typosquatting, dependency confusion, new-package age, install scripts and lockfile tamper. No package code is ever fetched or executed.

The GitHub check only fails on certainty: a known-malware advisory, or a critical CVE with a fix available. Heuristics and the LLM verdict agent are advisory-only rationale and never gate on their own.

Secret scanning runs a local regex pack plus an entropy floor against added lines only; matches post masked, and nothing is ever sent to a provider to verify. A daily sweep re-checks your dependency inventory independent of any PR and files a regular issue the moment a new advisory lands against a version you have installed, so your existing alert rules fire on it like anything else.

added

Pull request review, with production error context

A three-agent pipeline reviews PRs against the issues already open on the files they touch, then fact-checks its own findings before anything posts. Comment-only.

A PR opened, reopened, marked ready, or synchronized (or a @parsemend review comment on any PR in an opted-in repository) triggers three agents in sequence: one explores the diff with a tool loop, one writes structured findings, and a third fact-checks each finding (confirmed, uncertain, rejected) before anything is posted.

The differentiator is production context: open and regressed issues on the touched files from the last 90 days, capped at 10, plus a tool the agent can call for more history. Findings post as one inline-comment review and an edited-in-place walkthrough summary, never as an approval, a requested change, or a merge. Noise profiles (quiet, chill, assertive) control volume, and incremental re-review on synchronize dedupes by fingerprint.

Off by default per repository, and it never pushes commits, executes checked out code, or runs an install.

fixed

Ingest hardening

A gzip bomb could OOM the worker; a dedup key silently dropped events; hex parameterization collapsed distinct errors.

Four fixes worth naming, because each was a real defect rather than a tidy-up:

  • Decompression is now bounded on both ends. The compressed body is rejected before a byte is inflated, and the inflate runs in 4 KiB chunks that abort the moment cumulative output passes the cap. Inflating first and checking the length afterwards meant a few dozen KiB of zeros could expand into gigabytes and take the worker down with an uncatchable OOM instead of a clean 413.
  • The digest dedup key no longer silently drops events. Two distinct events arriving in the same envelope could collide on the key and one would vanish.
  • Hex parameterization no longer collapses distinct error messages. Messages differing only in a hex substring were being folded into one issue.
  • Future client timestamps are clamped. A device with a wrong clock could write an event into a partition that did not exist yet.
added

Issue triage UI

Issue list with status, level and project filters; issue detail with stack trace, breadcrumbs, tags and contexts.

The issue list filters by status, level and project, and searches title and culprit. The detail view renders the stack trace, the breadcrumbs leading up to the throw, the indexed tags and the event contexts.

Organizations are a tenancy boundary, and issues cannot be reassigned across it.

added

Rate limiting and reason-coded outcomes

Per-key fixed-window limiting that answers with 429, Retry-After and X-Sentry-Rate-Limits.

Over quota, Parsemend responds the way a Sentry SDK already expects: 429, a Retry-After header, and X-Sentry-Rate-Limits naming the category and scope. The SDK backs off without any change on your side.

Every dropped event is counted against a reason (invalid, rate_limited, filtered), so "where did my events go" has an answer.

added

Partitioned events table and retention

Events live in a database range partition per day. Expiring a day is a DDL statement, not a mass delete.

events is range-partitioned by received_at. A scheduled command creates partitions ahead of time and drops the ones past their retention window.

The alternative, DELETE FROM events WHERE received_at < ?, holds locks and leaves the table to vacuum for an hour. Dropping a partition takes milliseconds. Default retention is 90 days.

added

Issue counters, tags and regression detection

Denormalized counters, an indexed tag table, and resolved issues that flip back to regressed on the write path.

Each issue carries times_seen, an approximate user count backed by a Redis HyperLogLog, and a per-day event bucket. Tags, environments and releases are indexed into a key/value table rather than scanned out of JSON at query time.

A resolved issue that sees a new event flips to regressed as the event is written, with no cron job or nightly sweep involved.

added

Grouping cascade

Custom fingerprint, then in-app frame signatures, then exception type and value, then a parameterized message.

Grouping tries four strategies in order, and stops at the first that applies:

  1. A custom fingerprint, including {{ default }} expansion.
  2. Signatures of the in-app stack frames, with recursion collapsed.
  3. The exception type and value, skipping the type when the mechanism is synthetic.
  4. The message, with variable parts parameterized out.

Many hashes can fold into one issue through the group_hashes table, so merging two issues does not lose the events that arrived under the old hash.

added

Envelope parser with unknown-type tolerance

A byte-offset scanner handling both length-prefixed and newline-terminated items.

Sentry's envelope format delimits items two different ways: a length prefix, or a newline. Real SDKs use both, sometimes in the same payload, and a length-prefixed item may contain newlines of its own.

The parser is a byte-offset scanner rather than a line splitter, which is the only way to get this right. Golden-file fixtures captured from the real PHP and Node SDKs keep it that way.

added

Sentry-compatible ingest

The envelope endpoint, the legacy store endpoint, and all three DSN authentication forms.

Parsemend accepts events at POST /api/{project}/envelope and at the legacy POST /api/{project}/store. The DSN key is read from the X-Sentry-Auth header, from a sentry_key query parameter, or from the dsn field in the envelope header, whichever your SDK happens to use.

Envelope item types Parsemend does not store are consumed and counted rather than rejected. An SDK that sends a transaction alongside an error will not start erroring because we do not keep the transaction.

Subscribe via RSS.