@postman/postman-plugin 0.5.0 → 0.6.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +2 -2
  2. package/dist/hosts/factory.js +29 -3
  3. package/hooks/session-start-context.md +1 -1
  4. package/mcp.pi.json +2 -2
  5. package/package.json +1 -1
  6. package/skills/api-discovery/SKILL.md +7 -2
  7. package/skills/api-documentation/SKILL.md +2 -3
  8. package/skills/api-engineer/SKILL.md +13 -15
  9. package/skills/api-mocking/SKILL.md +4 -2
  10. package/skills/api-monitoring/SKILL.md +35 -25
  11. package/skills/api-simulation/SKILL.md +109 -74
  12. package/skills/api-simulation/reference/context_file.md +183 -149
  13. package/skills/api-simulation/reference/sim_yaml_schema.md +1 -1
  14. package/skills/api-testing/SKILL.md +3 -3
  15. package/skills/application-testing/SKILL.md +2 -2
  16. package/skills/ci-integration/SKILL.md +7 -5
  17. package/skills/cli-install/SKILL.md +29 -0
  18. package/skills/collection-schema-v3/SKILL.md +21 -11
  19. package/skills/collection-schema-v3/reference/environment.md +2 -0
  20. package/skills/collection-schema-v3/reference/globals.md +40 -0
  21. package/skills/collection-schema-v3/reference/http.md +149 -11
  22. package/skills/collection-schema-v3/reference/other_protocols.md +232 -86
  23. package/skills/datasets/SKILL.md +6 -5
  24. package/skills/datasets/reference/schema.md +51 -0
  25. package/skills/flows/SKILL.md +0 -1
  26. package/skills/performance-testing/SKILL.md +14 -1
  27. package/skills/performance-testing/references/gatling-import/README.md +141 -0
  28. package/skills/performance-testing/references/gatling-import/feeders.md +31 -0
  29. package/skills/performance-testing/references/gatling-import/injection.md +88 -0
  30. package/skills/performance-testing/references/gatling-import/mapping.md +91 -0
  31. package/skills/performance-testing/references/gatling-import/unsupported.md +31 -0
  32. package/skills/postman-mcp-server/SKILL.md +1 -1
  33. package/skills/variables/SKILL.md +2 -2
  34. package/skills/webhook-testing/SKILL.md +1 -1
  35. package/skills/workspaces/SKILL.md +53 -0
  36. package/skills/bootstrap/SKILL.md +0 -140
  37. package/skills/bootstrap/reference/cli_installation.md +0 -59
package/README.md CHANGED
@@ -235,8 +235,8 @@ exercise failure paths.
235
235
  `postman init` is idempotent and safe to run in any project. Run it before API
236
236
  engineering work to create the relevant local directories and make Postman
237
237
  skills available to guide the task, even if the project is already initialized.
238
- See [bootstrap](https://github.com/postmanlabs/postman-plugin/blob/main/skills/bootstrap/SKILL.md#start-with-postman-init) for setup
239
- options and workspace binding.
238
+ See [workspaces](https://github.com/postmanlabs/postman-plugin/blob/main/skills/workspaces/SKILL.md) for init's
239
+ workspace options and binding.
240
240
 
241
241
  Work done in a Postman folder produces artifacts: collection runs, lint
242
242
  results, request history, mock deployments. When that folder is connected to a
@@ -2,17 +2,43 @@ import { GIT_URL, REPO, isSameRepo, redact } from '../source.js';
2
2
  import { blocked, guard, mustProbeText, mustRun } from './shared.js';
3
3
  import { result } from './types.js';
4
4
  const MARKETPLACE = 'postman-plugin', PLUGIN_ID = `postman@${MARKETPLACE}`, SCOPE = 'user', NEXT = 'Restart Droid for the change to take effect.';
5
+ function rowsOfWrappedTable(text) {
6
+ const lines = text.split(/\r?\n/), headerAt = lines.findIndex((line) => /^[A-Z]+(?: [A-Z]+)*(?: {2,}[A-Z]+(?: [A-Z]+)*)+\s*$/.test(line));
7
+ if (headerAt === -1) {
8
+ return [];
9
+ }
10
+ const columns = [...lines[headerAt].matchAll(/[A-Z]+(?: [A-Z]+)*/g)].map((match) => ({ name: match[0], start: match.index })), rows = [];
11
+ for (const line of lines.slice(headerAt + 1)) {
12
+ const cells = columns.map(({ start }, i) => line.slice(start, columns[i + 1]?.start).trim()), previous = rows.at(-1), continuesPrevious = !cells[0];
13
+ if (!continuesPrevious) {
14
+ rows.push(Object.fromEntries(columns.map(({ name }, i) => [name, cells[i]])));
15
+ }
16
+ else if (previous) {
17
+ columns.forEach(({ name }, i) => { previous[name] += cells[i]; });
18
+ }
19
+ }
20
+ return rows;
21
+ }
22
+ export function installedPlugins(droidPluginList) {
23
+ const bracketedScopes = droidPluginList.split(/\r?\n/)
24
+ .map((line) => /^\s*(\S+@\S+)\s+\[(\w+)\]/.exec(line))
25
+ .filter((match) => match !== null)
26
+ .map(([, plugin, scope]) => `${plugin} [${scope}]`);
27
+ return bracketedScopes.length ?
28
+ bracketedScopes :
29
+ rowsOfWrappedTable(droidPluginList).map((row) => `${row.PLUGIN} [${row.SOURCE}]`);
30
+ }
5
31
  function hasInstalledPlugin(text) {
6
- return text.split('\n').some((line) => new RegExp(`^${PLUGIN_ID}\\s+\\[${SCOPE}\\]`).test(line.trimStart()));
32
+ return installedPlugins(text).includes(`${PLUGIN_ID} [${SCOPE}]`);
7
33
  }
8
34
  function marketplaceSource(text) {
9
- for (const line of text.split('\n')) {
35
+ for (const line of text.split(/\r?\n/)) {
10
36
  const match = /^\s*(\S+)\s+\(\d+ plugins?\)\s+(.+?)(?:\s+"[^"]*")?\s*$/.exec(line);
11
37
  if (match && match[1] === MARKETPLACE) {
12
38
  return match[2];
13
39
  }
14
40
  }
15
- return null;
41
+ return rowsOfWrappedTable(text).find((row) => row.MARKETPLACE === MARKETPLACE)?.SOURCE ?? null;
16
42
  }
17
43
  function sourceWithoutFactoryPrefix(source) {
18
44
  return source.replace(/^(?:github|url):/, '');
@@ -3,7 +3,7 @@ You have the Postman plugin.
3
3
 
4
4
  Before responding to any non-trivial API engineering task — designing, implementing, mocking, testing, monitoring, documenting, or deploying an API or Postman Flow — load the `postman:api-engineer` skill and follow it. It is the default entry point and routes to the specific postman skills from there. Pure questions and trivial one-line edits don't need it.
5
5
 
6
- When the intent is already specific, you may enter directly into the relevant skill instead: `postman:bootstrap` (link this repo to a Postman workspace), `postman:api-mocking`, `postman:api-testing`, `postman:api-monitoring`, `postman:flows`, `postman:ci-integration`, `postman:api-discovery`, `postman:ai-readiness`, `postman:performance-testing`, `postman:api-documentation`, `postman:variables` (where a value or secret belongs and how to reference it).
6
+ When the intent is already specific, you may enter directly into the relevant skill instead: `postman:api-mocking`, `postman:api-testing`, `postman:api-monitoring`, `postman:flows`, `postman:ci-integration`, `postman:api-discovery`, `postman:ai-readiness`, `postman:performance-testing`, `postman:api-documentation`, `postman:variables` (where a value or secret belongs and how to reference it).
7
7
 
8
8
  If you were dispatched as a subagent to execute a specific task, ignore this block — `postman:api-engineer` governs the orchestrating session, and it already shaped your dispatch.
9
9
 
package/mcp.pi.json CHANGED
@@ -6,8 +6,8 @@
6
6
  "description": "Postman workspaces, collections, specs, environments, mocks and monitors",
7
7
  "headers": {
8
8
  "X-Source": "postman-pi-plugin",
9
- "X-Plugin-Version": "0.5.0",
10
- "User-Agent": "postman-pi-plugin/0.5.0"
9
+ "X-Plugin-Version": "0.6.0-rc.0",
10
+ "User-Agent": "postman-pi-plugin/0.6.0-rc.0"
11
11
  }
12
12
  }
13
13
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@postman/postman-plugin",
3
- "version": "0.5.0",
3
+ "version": "0.6.0-rc.0",
4
4
  "description": "Postman's API engineering skills for coding agents: a Pi package, and an npx installer that sets up Claude Code, Codex, Cursor, Kimi Code, Factory Droid, OpenCode and Pi.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -10,6 +10,11 @@ must invent. Relationship context broadens investigation beyond the checkout:
10
10
  passing this service's own tests does not establish that its consumers can
11
11
  still use a changed interface.
12
12
 
13
+ Postman search, the Context Graph and dependency downloads work only for a
14
+ signed-in CLI. Check `postman status` before the first of them and sign in if
15
+ it reports signed out. If signing in isn't possible, don't run them; say which
16
+ sources were skipped.
17
+
13
18
  1. Choose the source by the question:
14
19
 
15
20
  | Need | Use |
@@ -47,8 +52,8 @@ still use a changed interface.
47
52
  not be present yet. The query uses the authenticated API key's team, not
48
53
  the repository's workspace binding; changing that binding cannot fix a
49
54
  query against the wrong organization's context.
50
- 5. Use **bootstrap**'s "Owning workspace versus dependency" distinction
51
- before importing. For a dependency, `postman dependency add
55
+ 5. Before importing, tell this repository's owning workspace from a
56
+ dependency. For a dependency, `postman dependency add
52
57
  <collection|environment|mock> <name-or-id>` declares and downloads the
53
58
  selected resource without rebinding the repository. Prefer the discovered
54
59
  ID; `--workspace <id>` disambiguates names. If the graph only identified a
@@ -14,8 +14,7 @@ with changes reviewable alongside code.
14
14
  interface for tooling; a Postman collection adds runnable requests,
15
15
  examples, and assertions. Maintain both when both uses matter, with an
16
16
  explicit direction of generation or synchronization so they do not become
17
- competing definitions. Local edits need **bootstrap** only when setup or
18
- bindings are unresolved.
17
+ competing definitions.
19
18
  2. When the spec is authoritative, reuse its operations with
20
19
  `postman spec generate collection <spec-path-or-id> -n "<collection-name>"`.
21
20
  Inspect the generated result before replacing an existing collection:
@@ -34,7 +33,7 @@ with changes reviewable alongside code.
34
33
  to keep credentials out of reusable requests and examples.
35
34
  5. Choose delivery by audience. Local artifacts support Git review;
36
35
  publishing to the bound workspace makes them available to teammates with
37
- access (see **bootstrap**). A workspace push does not itself publish a
36
+ access. A workspace push does not itself publish a
38
37
  public docs page or change permissions. For a public documentation link,
39
38
  use **postman-mcp-server**'s documentation workflow and the available
40
39
  publishing tool; establish the intended audience before public exposure.
@@ -16,10 +16,9 @@ guesswork each time work resumes.
16
16
  regression. Reuse the existing contract; update it where behavior changes.
17
17
  Flag design choices that make callers harder to implement or future changes
18
18
  harder to adopt, and explain the tradeoff. See **api-documentation**.
19
- 2. Choose the contract artifact for how it will be used: an OpenAPI spec describes
20
- the interface for tooling, while a Postman collection carries runnable requests,
21
- examples, and assertions. Reuse what exists; maintaining both is useful when
22
- both purposes matter. See **api-documentation**.
19
+ 2. A Postman collection records the contract in a form that runs. The CLI's
20
+ deterministic tools cheaply turn that one source into an OpenAPI spec, a
21
+ mock, an SDK, or a performance suite, so the contract is written once.
23
22
  3. Match verification to the behavior at risk. A saved collection can reuse auth,
24
23
  variables, payloads, and assertions without reconstructing requests; a one-off
25
24
  endpoint check can be smaller. Check the changed behavior and relevant existing
@@ -40,10 +39,8 @@ guesswork each time work resumes.
40
39
  your API, publish a mock of it in your service's own workspace, where their
41
40
  simulations look first; see **api-mocking**.
42
41
  6. Keep specs, collections, environments, and mocks in local files so changes can
43
- be diffed, reviewed, and reused in Git and CI. Use **bootstrap** when setup or
44
- workspace bindings are unresolved: reuse an existing local layout, pull the
45
- current service's existing workspace, or initialize a new project when neither
46
- exists.
42
+ be diffed, reviewed, and reused in Git and CI. `postman status` shows
43
+ what setup is in place, what is missing, and what closes each gap.
47
44
  7. `postman init` gives API engineering work a ready state. It scaffolds local structure: `postman/`
48
45
  directories for API artifacts. It installs skills in `postman/skills` folder with guidance on designing, implementing, and validating APIs.
49
46
  The command is idempotent and safe to rerun in an initialized project.
@@ -73,16 +70,17 @@ gap, such as an untested behavior or a consumer affected by an interface change.
73
70
  Decline unnecessary setup or scope and explain why it would not help the task.
74
71
 
75
72
  Important: If a CLI command says an operation isn't allowed because credits
76
- or usage are exhausted, or the current plan does not permit it, follow
77
- **bootstrap**'s "Subscription or usage limit" section instead of retrying or
78
- trying to find a workaround.
73
+ or usage are exhausted, or the current plan does not permit it, stop
74
+ retrying and tell the user that signing up or upgrading their plan is what
75
+ lifts it.
79
76
 
80
77
  ## Verification
81
78
 
82
79
  Report the changed contract or implementation, the checks actually run, and
83
80
  the guarantees their results support. Separate local, mocked, and live evidence;
84
- state any relevant consumer or upstream interaction still unverified.
81
+ state any relevant consumer or upstream interaction still unverified. Run
82
+ `postman status` last to confirm the setup the work relied on is still in place.
85
83
 
86
- If actual use exposes a CLI gap or misleading skill, see **bootstrap**'s
87
- "Reporting CLI and skill gaps" section so the defect can be addressed for future
88
- work.
84
+ If actual use exposes a CLI gap or misleading skill, report it through the
85
+ CLI's feedback channel after finishing the user's task, with a sanitized
86
+ reproduction and no secrets, user data, or proprietary content.
@@ -21,8 +21,10 @@ Several APIs at once, for a service, a frontend or a test suite? Use
21
21
 
22
22
  When the API belongs to another team, look for their published mock before
23
23
  writing one: theirs encodes their contract and their service's state; yours
24
- encodes a guess. It needs `postman login`; signed out, build one and say the
25
- owner search was skipped.
24
+ encodes a guess.
25
+
26
+ Every step below needs a signed-in CLI. Check `postman status` first; signed
27
+ out, skip to building one and say the owner search was skipped.
26
28
 
27
29
  1. Find the owner's workspace with `postman search workspaces "<service>" -o json`.
28
30
  Name the service plainly, as your code does, not by what it returns: a
@@ -19,43 +19,53 @@ exercise the guarantees users depend on.
19
19
  the linked workspace unless one is supplied. Inspect command-specific
20
20
  `-h` and available service options for supported schedules and limits.
21
21
  Creation starts an immediate run by default; `--no-run-now` avoids that
22
- when only scheduling was requested. A schedule expressed in the host's
23
- default timezone can fire at the wrong operational time.
22
+ when only scheduling was requested. Pass `--timezone` with the zone the
23
+ user means (for example `America/New_York`); without it the schedule uses
24
+ the zone of the machine running the CLI. Leave the month field as `*`; to
25
+ limit a schedule to certain months, write them as three-letter names such
26
+ as `jan`, not numbers.
24
27
  3. Choose a Postman region for a reachable public API. Use a self-hosted
25
28
  runner when the target is reachable only inside the user's network;
26
29
  running one adds infrastructure to maintain. `postman runner regions`
27
- provides valid hosted locations and `runner list` provides registered
28
- private runner IDs. `monitor create/update --runner` accepts either;
30
+ provides valid hosted locations and `runner list --json` the full IDs of
31
+ registered private runners. `monitor create/update --runner` accepts either;
29
32
  multiple locations help distinguish API failures from regional reachability.
30
- 4. Preserve monitor identity when updating schedule or run settings.
31
- `monitor update` cannot change its collection or environment and does not
32
- pause it; use `pause`/`resume` for that. A different collection/environment
33
- requires a replacement, so plan the handoff before deleting the old
34
- monitor and its continuity. Permanent deletion needs explicit intent.
33
+ 4. Update a monitor in place to keep its run history.
34
+ `monitor update` cannot change the collection, and cannot pause or resume
35
+ the monitor: use `monitor pause`/`monitor resume` for that. `update -e`
36
+ swaps the environment and `--clear-environment` removes it. A different
37
+ collection requires a replacement, so plan the handoff before deleting the
38
+ old monitor and its continuity. Permanent deletion needs explicit intent.
35
39
  5. Use `postman monitor run <id>` for an immediate verdict, such as after a
36
40
  deploy. `--async` returns a job handle when the caller need not wait.
37
- The CLI timeout caps waiting, not execution; after a timeout, inspect
38
- the submitted job instead of sending duplicate traffic or reporting failure.
39
- 6. Diagnose at the level of the evidence. `monitor jobs list <monitor-id>`
40
- finds jobs, `monitor jobs get <job-id>` shows terminal state and regional
41
- outcomes, and `monitor runs get <run-id>` shows assertions within an
42
- attempt. A failing region, a connection error, and a failed assertion
43
- imply different fixes. Preserve normal exit-code failures for CI gates.
41
+ The CLI timeout caps waiting, not execution: after a timeout, read the job
42
+ with `monitor jobs get <job-id>`; its state is the verdict.
43
+ 6. Answer each failure question at its level. `monitor jobs list
44
+ <monitor-id>` finds jobs, `monitor jobs get <job-id>` shows terminal state
45
+ and regional outcomes, and `monitor runs get <run-id>` shows assertions
46
+ within an attempt. A failing region, a connection error, and a failed
47
+ assertion imply different fixes. For a trend across runs, such as which
48
+ request got slow, use `monitor metrics <monitor-id>`. In a CI gate, run
49
+ `monitor run` without `-x`, so a failed run fails the build.
44
50
 
45
- For discovery, `monitor list` supports workspace and collection filters;
46
- use its returned cursor for pagination rather than offset. Its runner filter
51
+ For discovery, `monitor list` supports workspace and collection filters; to
52
+ page it, pass `--cursor` with the value from the previous page. Its runner filter
47
53
  is for a self-hosted ID and cannot be combined with other filters; a page-local
48
54
  name filter does not establish absence across all pages.
49
55
 
50
- For a private runner, use `runner start` with the registered ID and key and
51
- verify that it connects before assigning runs. Inspect its help for proxy,
52
- private CA, residency, and health-metric options only when the network requires
53
- them. Runner activity is reported by default; `--no-report-events` disables
54
- that reporting when the task requires it. Use **bootstrap** for unresolved
55
- authentication rather than placing runner keys in repository files.
56
+ For a private runner, use `runner start` with the ID and key from the runner
57
+ created in Postman, and verify it is reporting in before assigning runs: a
58
+ recent `Last ping` in `runner list` (`lastPingAt` under `--json`; `never`
59
+ means it has not connected). Inspect its help for proxy, private CA,
60
+ residency, and health-metric options only when the network requires them.
61
+ Runner activity is reported by default; `--no-report-events` disables that
62
+ reporting when the task requires it. Pass the runner key at runtime, from the
63
+ user or a secret store (for example `--key "$RUNNER_KEY"`), and keep it out of
64
+ files in the repository. If a `monitor` or `runner list` command fails on
65
+ authentication, sign in.
56
66
 
57
67
  ## Verification
58
68
 
59
69
  Report the actual monitor configuration or terminal job/run outcome, including
60
70
  where it executed and which checks failed. A created monitor, accepted job,
61
- or connected runner alone does not prove the API passed its health checks.
71
+ or a runner reporting in alone does not prove the API passed its health checks.
@@ -1,27 +1,50 @@
1
1
  ---
2
2
  name: api-simulation
3
- description: Runs your code for real against stand-ins for the HTTP services it calls, served together as one environment on one local port or one deployed URL, whether that code is a service you're changing, a frontend, a test suite or a demo. Use when you add or change code that calls other services and need to run it, test it, prove a fix or reproduce an upstream failure (timeouts, 5xx, 409, 429) end to end, locally or in CI, without the real services because they're unreachable, need credentials, cost money, have side effects or don't exist yet. Also answers what happens to a request, or to the data it writes, when a service it calls goes down, is slow or returns errors ("what happens to a booking if the email service is down?"), by running each failure instead of reading the code. Applies even when nobody says mock or simulation. To give a frontend or another team a stand-in for an API, use api-mocking. Covers `postman simulation`.
3
+ description: Runs services, frontends, tests or demos against stand-ins for their HTTP dependencies, served as one environment locally or at a deployed URL. Use when you add or change code that calls other services and need to run it, test it, prove a fix or reproduce an upstream failure (timeouts, 5xx, 409, 429) end to end, locally or in CI, without the real services because they're unreachable, need credentials, cost money, have side effects or don't exist yet. Also answers what happens to a request, or to the data it writes, when a service it calls goes down, is slow or returns errors ("what happens to a booking if the email service is down?"), by exercising relevant failures and observing caller outcomes. Applies even when nobody says mock or simulation, and a `postman/simulations/` directory in the repository is itself a reason to load this before changing code it covers. To give a frontend or another team a stand-in for an API, use api-mocking. Covers `postman simulation`.
4
4
  ---
5
5
 
6
6
  # API Simulation
7
7
 
8
- A simulation serves several mocks as one environment, each reached by its
9
- routeKey: as a path prefix by default, or as an `x-mock-slug` header when the
10
- caller's paths can't change.
11
-
12
- Run your code against it rather than stubbing its HTTP client in tests or
13
- calling the real services. A stub skips the client, config, timeouts and
14
- error handling that will run in production; the real services need
15
- credentials and leave side effects. A simulation runs that code over real
16
- HTTP, the same way in CI, and its log shows what each dependency was asked.
17
-
18
- Do only what the task needs. If a `.sim.yaml` in `postman/simulations/`
19
- already covers it, run that one, and read the `<name>.context.md` beside it
20
- first: it holds the commands, the preconditions and the failures earlier runs
21
- hit, so reading it costs less than rebuilding any of that from the `.sim.yaml`
22
- and the handlers. One request through the changed path proves a change; build
23
- failure variants only when asked how the code fails or when it must survive a
24
- failure.
8
+ Simulation lets you control how dependencies behave and explore how your code
9
+ responds to different outcomes. This makes it easier to test assumptions
10
+ repeatedly without real calls changing data, spending money, or notifying
11
+ someone. Simulation context records those assumptions, the evidence supporting
12
+ them, and what remains unknown. As sessions build on this context, it helps
13
+ surface incorrect assumptions and avoid repeated investigation.
14
+
15
+ Together, the simulation and its context provide a place to explore changes
16
+ and identify what still needs validation against the real dependencies.
17
+
18
+ Check whether an existing simulation in `postman/simulations/` covers the
19
+ dependency interactions relevant to the task. Reusing its mocks and wiring
20
+ can avoid rebuilding an environment; extend it only where the behavior you
21
+ need to exercise is missing.
22
+
23
+ The `<name>.context.yaml` beside a simulation records those assumptions, their
24
+ supporting evidence, and unresolved questions so later sessions can build on
25
+ earlier findings. For example, a timeout from `/payments` does not establish
26
+ whether the payment failed or completed before the response arrived. The
27
+ context file will document what has been established about the real provider
28
+ and identify what still needs verification.
29
+
30
+ A simulation serves several mocks as one environment: by default behind a
31
+ proxy that answers for the dependencies' own hostnames, so the code under test
32
+ keeps the base URLs it ships with, or on one local port where each member is
33
+ reached by its routeKey.
34
+
35
+ Simulation adds value when the result depends on real HTTP behavior, such as
36
+ client configuration, serialization, timeouts or retries, and the real
37
+ dependencies are unavailable or unsuitable for the exercise. Stubbing the
38
+ HTTP client can bypass those behaviors. Choose verification that exercises
39
+ what matters to the task: an existing test may already answer a local logic
40
+ question, while a claim about the provider may need its contract or a real
41
+ service check. A simulation's log shows what each stand-in was asked.
42
+
43
+ Define the expected outcome and what observation would distinguish correct
44
+ from incorrect behavior, including side effects when relevant. A request
45
+ through the changed path shows that it ran; its response and resulting state
46
+ determine whether the expectation held. Choose boundary and failure cases
47
+ from the behavior changed and the consequences of getting it wrong.
25
48
 
26
49
  `postman simulation` needs CLI 1.70.0 or later (`postman --version`; an older
27
50
  CLI answers `postman simulation -h` with its general help).
@@ -33,7 +56,9 @@ CLI answers `postman simulation -h` with its general help).
33
56
  shared code; ask about the repo by its `git remote` name, because a close
34
57
  name matches another repo.
35
58
  - **Each member needs a mock: see `api-mocking`,** which looks for the owning
36
- team's published mock before building one. For a question, one built from
59
+ team's published mock before building one. Finding and pulling an owner's
60
+ mock needs a signed-in CLI; check `postman status` first, and signed out,
61
+ build each mock and record that the owner search was skipped. For a question, one built from
37
62
  the contract will do; one that invents responses can send the caller down a
38
63
  path the real service never would. In a mock you build, answer `501` for calls this path
39
64
  doesn't make: a `404` reads to the caller like a real "not found".
@@ -52,45 +77,37 @@ The run is a server that never exits, so a foreground command never returns.
52
77
  Start it in the background, its log in a file:
53
78
 
54
79
  ```bash
55
- postman simulation run postman/simulations/checkout-dev.sim.yaml --port 4900 --output ndjson > sim.ndjson 2> sim.err &
80
+ postman simulation run postman/simulations/checkout-dev.sim.yaml --proxy --output ndjson > sim.ndjson 2> sim.err &
56
81
  ```
57
82
 
58
- `--port` is optional. It's up when `sim.ndjson` has a `listening` event; a
59
- start-up error is in `sim.err`. That event carries the bound port and each
60
- member's address, so take the base URLs from it rather than from the port you
61
- asked for. Stop it with
83
+ `--proxy` is how to run it unless something below rules it out: nothing about
84
+ the code changes for the run — not a base URL, not a config file, not an SDK's
85
+ built-in host — and because nothing the proxy answers for has to resolve, an
86
+ internal hostname with no DNS record works.
87
+
88
+ It's up when `sim.ndjson` has a `listening` event; a start-up error is in
89
+ `sim.err`, a busy proxy port among them. Stop it with
62
90
  `pkill -INT -f "simulation run .*<file>.sim.yaml"`. Nothing reloads: restart
63
91
  it after a mock edit.
64
92
 
65
- Point the caller at it without changing what the code does once deployed.
66
- Under path routing, swap only the host and keep the path:
67
- `https://catalog.internal.example.com/v2` becomes
68
- `http://127.0.0.1:4900/catalog/v2`; a dropped `/v2` is the usual cause of a
69
- `404`. A hard-coded base URL should read an environment variable with
70
- today's value as the default. If the code mustn't change at all, run it
71
- behind the proxy instead, below.
72
-
73
- ## Through a proxy, when no base URL can change
74
-
75
- `simulation run <file.sim.yaml> --proxy` puts the members behind a local
76
- forward proxy that answers for the dependencies' own hostnames, so the code
77
- keeps the base URLs it ships with. Any other host passes through to the real
78
- service. Reach for it when hostnames are hard-coded, built from config the
79
- change shouldn't touch, or owned by an SDK — and because nothing it answers
80
- for has to resolve, an internal hostname with no DNS record works.
81
-
82
93
  Read `postman simulation run --help` before driving it. The flags, what the
83
94
  caller's own process needs in order to reach the proxy, and what to do about a
84
95
  client that ignores it are all there and change with the CLI, so take them
85
96
  from the command rather than from here.
86
97
 
87
- Two things decide whether a proxied run proves anything. A member with no
88
- `origin:` in the `.sim.yaml` is never matched, so its traffic reaches the real
98
+ What decides whether a proxied run proves anything is `origin:`. A member with
99
+ none in the `.sim.yaml` is never matched, so its traffic reaches the real
89
100
  service and a run can come up having intercepted nothing — `simulation create`
90
101
  copies that field from the mock's manifest, so editing the manifest alone
91
102
  won't fix it ([reference/sim_yaml_schema.md](reference/sim_yaml_schema.md)).
92
- And conditions don't apply here: member `scenarios` are ignored, so failures
93
- need the one-port run.
103
+
104
+ ## Running it on one port instead
105
+
106
+ `--port` puts every member on one local port, each addressable by its routeKey,
107
+ with the code under test pointed at that port. Reach for it when a client has
108
+ no proxy setting to honour, and when you want to address a member yourself —
109
+ each one keeps a stable URL for the whole run, so a mock's control routes and
110
+ its individual responses are a curl away.
94
111
 
95
112
  ## Reading the log
96
113
 
@@ -98,8 +115,8 @@ A passing test command doesn't show the dependency path ran: read
98
115
  `sim.ndjson`. A member with no `request` events isn't wired or isn't on this
99
116
  path. Some answers come from the simulation itself and mean wiring, not code:
100
117
 
101
- - `404 Unknown simulation member`: a base URL lost its routeKey, or a client
102
- sent the wrong `x-mock-slug`.
118
+ - `404 Unknown simulation member`, on a one-port run: a base URL lost its
119
+ routeKey, or a client sent the wrong `x-mock-slug`.
103
120
  - `501`, or a generated mock's `404 Endpoint not defined`: a call the mock
104
121
  doesn't model yet.
105
122
  - `502 Proxy error`: the member's process died, usually an async throw in a
@@ -108,12 +125,20 @@ path. Some answers come from the simulation itself and mean wiring, not code:
108
125
 
109
126
  ## When a dependency goes down
110
127
 
111
- Run it rather than reason from the code: each way of going down takes a
112
- different path through the caller, and a stub skips the client code that
113
- picks the path. Fail the one dependency in each shape that matters, a run
114
- each, with the others answering normally:
128
+ Choose failures from the outcome the user needs to understand. A failure
129
+ before a write, a timeout after a write may have completed, and a failure
130
+ during compensation can expose different risks: lost work, duplicate writes
131
+ or unreleased resources. Read the caller to identify relevant paths, then
132
+ exercise the ones whose runtime behavior remains uncertain.
115
133
 
116
- - **Unreachable:** point its base URL at a port nothing listens on.
134
+ Isolating one failure helps attribute the result. Combine failures or model
135
+ partial completion when the question depends on their interaction. The
136
+ injection must represent the event being investigated: delaying a response
137
+ alone does not establish whether a write completed before the timeout.
138
+ Examples of available techniques:
139
+
140
+ - **Unreachable:** point its base URL at a port nothing listens on. This one
141
+ needs the one-port run, since under `--proxy` the base URLs are the point.
117
142
  - **Hanging:** give its member a `latency` condition longer than the
118
143
  client's timeout. If the client sets none, that is the finding: Node's
119
144
  `fetch` waits about five minutes, so say so rather than wait it out.
@@ -131,19 +156,24 @@ stock reserved and never released.
131
156
 
132
157
  ## Its context document
133
158
 
134
- Every simulation is created with a `<name>.context.md` beside it, holding what
135
- running this one has taught: the commands that start it and prove it's up, the
136
- preconditions and what breaks when one fails, what it takes for granted about
137
- the dependencies themselves, the data seeded to test with, the failures earlier
138
- runs already hit, and what a passing run still doesn't prove. The `.sim.yaml` says what the simulation is, not how it behaves, so
139
- this is the file that saves a session the search. A new one is mostly
140
- `@todo`s, which are the questions a first real run answers.
141
-
142
- Every line passes one test — the repo doesn't already state it — so it stays
143
- about a screenful, and a claim carries the date and the run that established
144
- it, because the log it came from isn't committed. Its sections and conventions
145
- are in [reference/context_file.md](reference/context_file.md); read that
146
- before writing it back.
159
+ Every simulation is created with a `<name>.context.yaml` beside it, holding
160
+ what the code is believed to rely on about the dependencies it calls — who the
161
+ caller is taken to be, which plan or permission is assumed, the order calls go
162
+ in, what gets retried, the shape of the data — and what each belief rests on.
163
+ The `.sim.yaml` says what the simulation is, not what the services it stands in
164
+ for do, so this is the record that saves a session the search.
165
+
166
+ Read relevant claims before investigating the dependencies, and assess whether
167
+ their evidence still applies to this task. Write what you established back
168
+ into the document before you finish. Each claim carries a `status`,
169
+ the `reason` the evidence adds up to it, the `verification` that was done and
170
+ what it showed, and a `source` to re-check it against, so the next session can
171
+ tell a claim a contract promises from one a request actually demonstrated.
172
+ Preserve existing claims and their evidence when updating the file, including
173
+ unresolved assumptions and historical findings. Its fixed schema and guidance
174
+ on evidence and reuse are in
175
+ [reference/context_file.md](reference/context_file.md); read that before
176
+ writing to it.
147
177
 
148
178
  ## Keeping it
149
179
 
@@ -173,16 +203,21 @@ first. It fails on a pulled member, which keeps its owner's `id:`; copy it to
173
203
 
174
204
  ## Before you say it works
175
205
 
176
- Claim nothing until what you're testing actually ran: a service printed
177
- that it's listening and answered your request, or the frontend or test
178
- suite finished, and its calls are in the log. If its start command exited
179
- or hung, the run proved nothing; say so and why. Say what a pass proves,
206
+ Claim a simulation passes only after the code under test ran and you observed
207
+ the expected response or state change. Use its calls in the log to confirm
208
+ the dependency path was exercised; for injected failures, use the caller
209
+ outcomes described above. If startup failed or the relevant path never ran,
210
+ report that limitation. Say what a pass proves,
180
211
  your code against these stand-ins rather than the real services, what still
181
212
  needs the real service before release, and where each mock came from,
182
213
  including when you skipped the owner's.
183
214
 
184
- Then write the run back into `<name>.context.md`, so the next session starts
185
- where this one ended: the `@todo`s it answered, whatever it found wrong, a
186
- precondition you had to discover, what broke and why, and which members served
187
- or stayed silent — the last is a line every run adds, so a member silent across
188
- several runs reads as a pattern rather than a one-off.
215
+ Then write what you established back into `<name>.context.yaml`, so the next
216
+ session starts where this one ended. Add or update claims that help a later
217
+ session reuse the findings. For each claim the run settled or contradicted,
218
+ update its `status`, the `verification` that was done and the `source` to
219
+ re-check it against. Scope what you claim to what you actually
220
+ exercised — "held in the scenarios run" rather than "works" — since the record
221
+ is read later as evidence, and the two don't mean the same thing.
222
+ [reference/context_file.md](reference/context_file.md) has what each field is
223
+ for.