Skip to content

Releases: heyvaldemar/cypress-cloud-triage-agent

Release list

v1.0.0

Choose a tag to compare

@heyvaldemar heyvaldemar released this 27 Oct 17:37

The first release: a triage agent for failed Cypress runs, on kind, built on the assumption that the failing test's text will talk the agent into something.

What is in it

  • A run.completed receiver (manifests/receiver/). It checks X-Cypress-Signature in constant time before reading anything, takes a timestamp only as digits within five minutes either way, uses the signature as the replay key and the signed body as the event's type, and starts one triage per failed run. The triage Job carries the project ID and run number and nothing else from the payload.
  • A CI trigger (scripts/send-run.py): the same body and signature Cypress Cloud sends, built from the run's results. A live Cypress Cloud webhook needs the Team plan or above; on the Starter plan the end of the CI job sends it, and the receiver cannot tell the two apart.
  • A door in front of Cloud MCP (manifests/cloud-mcp/): Cloud MCP's tool names, two of them granted to the agent, and only for the run its pod was started for. On kind it serves a real Cypress 16.2.0 run from files.
  • A notifier (manifests/notifier/): the agent's one way out. It writes the first line in Slack itself, from Cypress's counts, and quotes the agent's words with Slack's control characters escaped, outside addresses broken and previews off.
  • Admission that holds every Job and Pod in the agents' namespace to the receiver's template: one image, one script, two door tokens, five environment variables, its own resolver, ten minutes.
  • A stand-in agent that does everything a customer's note in a failure message tells it to, every run, with no model and no API key.

What was found while building it

  • The notifier took a link's host as the text after the last @ before the first /, so https://example.net?x=@cloud.cypress.io/ passed as a Cypress link while a browser opens example.net. An automated review of the first commit found it; the test written for it failed on that code, and the host now comes from urllib.parse.urlsplit (61975df).
  • The first e2e run summarised 62 of the 91 checks it ran: four steps fed their verdicts through a pipe, where a failure would not have reached the exit status. Fixed before the first commit, and shown red with a deliberately broken check.
  • docs.cypress.io's Node example computes Number(timestamp), and NaN passes its five-minute check. The timestamp is signed, so only a holder of the secret could send one: a mistake in an example, not a way in. The receiver takes digits only.

How it was checked

On d737602, the commit before this one (which changes CHANGELOG.md only):

  • Triage e2e 40541033689: a fresh kind cluster, Cypress in its pinned image, 91 checks passed, including eleven refused deliveries, three replays that start nothing, twenty Jobs refused at admission and the receiver's own admitted.
  • Verify 40541033960: actionlint, shellcheck, kubeconform, 50 unit tests for the three doors, and nineteen planted violations, each caught.

The two runs before it, on 76334a5 and 61975df, passed the same 91 e2e checks.

Not claimed in this release: a delivery from a live Cypress Cloud webhook, and the Cloud MCP door forwarding to mcp.cypress.io. Both need a Cypress plan and a token, and wait for a run that proves them.

Verifying this release

cosign verify-blob cypress-cloud-triage-agent-v1.0.0.tar.gz \
  --bundle cypress-cloud-triage-agent-v1.0.0.tar.gz.sigstore.json \
  --certificate-identity-regexp '^https://github.com/heyvaldemar/cypress-cloud-triage-agent/' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

slsa-verifier verify-artifact cypress-cloud-triage-agent-v1.0.0.tar.gz \
  --provenance-path cypress-cloud-triage-agent-v1.0.0.intoto.jsonl \
  --source-uri github.com/heyvaldemar/cypress-cloud-triage-agent \
  --source-tag v1.0.0