Repository navigation
feat(journeys): journey file format and prescale journeys verify - #7
Merged
Merged
Conversation
This was referenced Nov 2, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A journey is a user's path through the app (log in, add to cart, place an order) saved as the requests it makes, in the app's own repo as
prescale/journeys/<name>.yaml. This adds the file format (version 1) and two commands:prescale journeyslists them, andprescale journeys verify <url>replays each once, as one user, naming the step that no longer answers as expected. A journey that fails with no load is stale (the app changed, or it's broken), never "broke under load". Replaying journeys at load builds on this in the next PRs.{{name}}from an earlier step'sextract(body.<field>,header.<name>),{{unique.email}}/{{unique.id}}fresh per run,{{env.NAME}}for secrets.http://host/app+/api/cart), and any request or redirect to another scheme, host or port fails the step.--allow-writes;side_effectanddestructivejourneys are never loaded./checkout) and two journeys inexamples/journeys/.How it was verified
Against the real example shop:
/api/cart→/api/basketin a copy):stale checkout … add to cart POST /api/basket returned 404, expected 201: {"error": "not found"}, step 3(not run), exit 1.couldn't reach the app (ConnectError), reported as "couldn't run", not stale; exit 1.SHOP_PASSWORDunset: refused before any request, exit 2. Writes against a non-local host without--allow-writes: refused, exit 2.connection_pool (high confidence) · culprit /checkout.cli/containsprescale_cli/journeys/andcommands/journeys.py.ruff check cli/src: clean ·pytest cli/tests -q: 285 passed (50 new).Risk
Tier: risky · Public surface: new command
prescale journeys/journeys verify(exit 0 all replay, 1 stale or unreachable, 2 invalid input or refused); journey file format v1.Rollback: reverting removes the command and loader; this slice writes nothing to disk and uploads nothing. What a revert can't undo is files users have already committed, which is why the format is versioned and strict (unknown fields rejected), so later versions can add fields without guessing.
Fresh-context review: blocked on one real escape. A path like
//other-host/x, or a rendered/{{next}}where the server returns/other-host/x, madeurljoinsend the request (including writes) to another host, past the--allow-writesgate. Reproduced and fixed: the loader rejects//, URLs are built by appending to the base (neverurljoin), and a request hook checks the origin of every request, redirect hops included. Also fixed from the review: cross-origin redirects, rich-markup crashes on step names, numeric header values, false positives and gaps in the secrets rule, non-finite weights, and the example shop dropping connections on bad input. Each has a test.Notes for review
Path semantics are now part of format v1: a step's path is relative to the URL you run against, including any base path.
Generated by Claude Code