Skip to content

Audit fixes: qualify() helper, docs onboarding, CI hardening, testing coverage#294

Merged
btravers merged 10 commits into
mainfrom
audit-fixes
Jul 9, 2026
Merged

Audit fixes: qualify() helper, docs onboarding, CI hardening, testing coverage#294
btravers merged 10 commits into
mainfrom
audit-fixes

Conversation

@btravers

@btravers btravers commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes from a full project audit (code health, security, DX):

New API — qualify() (worker, minor)

  • qualify(type, options?) builds the fromPromise qualifier, replacing the ~8-line ApplicationFailure.create boilerplate repeated in every activity. Error rejections keep their message and are preserved as cause; nonRetryable / details / fallback message supported. Always wraps so the declared type is guaranteed for retry policies. Dogfooded in the order-processing example.

Packages

  • @temporal-contract/testing: @temporalio/client and @temporalio/worker moved to peer dependencies — their types leak through the public it fixture (breaking, see changeset; edit .changeset/audit-fixes.md down to minor if you consider it non-breaking in practice). Phantom config entry dropped from files, keywords added.
  • All packages: sideEffects: false; worker's last explicit any replaced with ChildWorkflowHandle<Workflow>; JSDoc examples fixed to ESM-correct imports.
  • Example workflow rethrows cancellation (isCancellation) instead of swallowing it in the notification catch.

Tests

  • Testing package had zero tests; extension.ts and global-setup.ts now covered (mocked testcontainers/Temporal). New spec for contract/src/format.ts.

CI

  • All actions pinned to commit SHAs; test job matrix adds Node 22.19.0 (the declared engines floor); timeout-minutes everywhere; release no longer builds twice.

Docs

  • Getting-started now compiles as written (qualify, createWorker + workflowsPathFromURL instead of require.resolve); .js extensions on all ~45 relative snippet imports; 12 require.resolve sites replaced.
  • Installation prerequisites corrected (Node 22.19+, TS 6.0); testing package requirements (Vitest 4, ESM-only, Docker) stated.
  • New Testing guide; README gets full peer install block and a Stability & Versioning section; migration guides demoted to a collapsed sidebar group; stale claims fixed; stray docs/package-lock.json removed.

Test plan

  • pnpm lint / pnpm format / pnpm knip clean
  • pnpm typecheck — 12/12 tasks
  • pnpm test — 9/9 tasks (incl. 6 new testing-package tests, 12 new format tests, 6 new qualify tests)
  • pnpm test:integration — 8/8 tasks against a real Temporal server (Docker)
  • pnpm build + typedoc regen + VitePress docs build (validates dead links, incl. the new /guide/testing)

🤖 Generated with Claude Code

Benoit Travers and others added 5 commits July 9, 2026 09:45
Builds the fromPromise qualifier every activity previously hand-wrote:
an Error rejection keeps its message and is preserved as cause, with
nonRetryable/details/message (non-Error fallback) options. Always wraps
so the declared type is guaranteed for retry policies. Dogfooded in the
order-processing example, which drops its private helper.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- testing: move @temporalio/client and @temporalio/worker to peer
  dependencies (their types leak through the public it fixture), drop
  the phantom config entry from files, add keywords
- all packages: declare sideEffects: false for tree-shaking
- worker: replace the last explicit any with ChildWorkflowHandle<Workflow>;
  fix JSDoc examples to ESM-correct imports (.js extensions,
  workflowsPathFromURL instead of require.resolve)
- example: rethrow cancellation in the notification catch so a cancel
  request cannot be swallowed
- rules: correct stale peer-dep table and overrides section

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The testing package had zero tests despite being the harness for all
integration suites; extension.ts and global-setup.ts are now covered
with mocked Temporal connections/testcontainers. contract's format.ts
gets a spec for every path-rendering branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- all first- and third-party actions pinned to full SHAs (Dependabot's
  github-actions ecosystem keeps them updated)
- the test job now runs a matrix of .node-version (24.x) and 22.19.0,
  the engines floor declared by the published packages
- timeout-minutes on every job; release no longer builds twice (the
  publish script already runs pnpm build)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- getting-started now compiles as written: qualify() in activities,
  createWorker + workflowsPathFromURL instead of require.resolve
- .js extensions on all relative imports in guide snippets; all
  require.resolve sites replaced with ESM-safe resolution
- installation prerequisites corrected (Node 22.19+, TypeScript 6.0)
  and the testing package's Vitest 4/ESM/Docker requirements stated
- new Testing guide documenting the globalSetup + it.extend wiring
- README: full peer-dependency install block, qualify() in the quick
  example, Stability & Versioning section; migration guides moved to a
  collapsed sidebar group; stale v0.5.0 claim removed
- CONTRIBUTING floors aligned with engines; stray docs/package-lock.json
  removed

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 9, 2026 07:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR applies a broad “audit fixes” pass across temporal-contract, focusing on reducing activity boilerplate via a new qualify() helper, aligning docs/snippets with the repo’s ESM + .js import requirements, strengthening CI, and adding missing test coverage.

Changes:

  • Added qualify(type, options?) to @temporal-contract/worker/activity and updated examples/docs to use it.
  • Hardened workflows/docs for ESM correctness (.js extensions, workflowsPathFromURL(...) vs require.resolve), and improved onboarding docs.
  • Expanded coverage (new unit specs for worker qualify + contract formatters; introduced a Vitest setup + tests for @temporal-contract/testing) and tightened CI (timeouts, matrix, pinned actions).

Reviewed changes

Copilot reviewed 37 out of 39 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
README.md Updates public-facing examples/install instructions to use qualify and peer-dep install guidance.
pnpm-lock.yaml Lockfile updates reflecting dependency/peer-dep reshuffles (notably testing package).
packages/worker/src/workflow.ts Fixes JSDoc snippet imports to be ESM-correct (.js).
packages/worker/src/worker.ts Updates JSDoc to use workflowsPathFromURL and ESM imports.
packages/worker/src/child-workflow.ts Removes internal any in child workflow handle typing.
packages/worker/src/activity.ts Introduces qualify() helper and updates docs/examples within the module.
packages/worker/src/activity.spec.ts Adds test coverage for qualify() behavior.
packages/worker/package.json Declares sideEffects: false for better tree-shaking.
packages/testing/vitest.config.ts Adds Vitest config with coverage + injected testcontainers address.
packages/testing/src/global-setup.spec.ts Adds unit coverage for Vitest globalSetup via mocked testcontainers.
packages/testing/src/extension.spec.ts Adds unit coverage for it fixture extension (mocked Temporal connections).
packages/testing/package.json Adds keywords, sideEffects: false, Vitest scripts, and moves Temporal SDK deps to peers.
packages/contract/src/format.spec.ts Adds tests for formatIssue / summarizeIssues rendering.
packages/contract/package.json Declares sideEffects: false.
packages/client/package.json Declares sideEffects: false.
examples/order-processing-worker/src/application/workflows.ts Ensures workflow cancellation propagates (isCancellation).
examples/order-processing-worker/src/application/activities.ts Dogfoods qualify() to remove repeated ApplicationFailure.create boilerplate.
docs/package-lock.json Removes stray lockfile from docs.
docs/guide/worker-usage.md Updates snippets for ESM .js imports and workflowsPathFromURL.
docs/guide/worker-implementation.md Updates snippets for ESM .js imports.
docs/guide/troubleshooting.md Updates snippets to workflowsPathFromURL and qualify.
docs/guide/testing.md Adds a new testing guide for @temporal-contract/testing.
docs/guide/result-pattern.md Updates imports in snippets to ESM .js.
docs/guide/nexus-integration.md Updates snippets to ESM .js and workflowsPathFromURL.
docs/guide/installation.md Updates prerequisites and adds warnings about testing package requirements.
docs/guide/getting-started.md Updates onboarding snippets to use qualify and ESM-safe workflow path resolution.
docs/guide/entry-points.md Updates workflow path examples to workflowsPathFromURL and .js exports.
docs/guide/client-usage.md Updates snippet imports to ESM .js.
docs/guide/activity-handlers.md Adds qualify guidance and converts examples to use it + ESM .js imports.
docs/.vitepress/config.ts Adds Testing guide nav entry; moves migration guides into a collapsed group.
CONTRIBUTING.md Aligns prerequisites with supported Node/pnpm versions.
.github/workflows/release.yml Adds timeout, pins actions to SHAs, removes redundant build step.
.github/workflows/deploy-docs.yml Adds timeouts and pins actions to SHAs.
.github/workflows/ci.yml Adds timeouts, pins actions, expands test matrix (Node floor), renames artifacts.
.github/actions/setup/action.yml Adds node-version override input; pins setup/cache actions to SHAs.
.changeset/qualify-helper.md Changeset documenting new qualify() helper release.
.changeset/audit-fixes.md Changeset summarizing audit fixes and the testing package breaking change.
.agents/rules/handlers.md Updates handler guidance to mention qualify().
.agents/rules/dependencies.md Updates peer-dependency policy table and security override guidance.
Files not reviewed (2)
  • docs/package-lock.json: Generated file
  • pnpm-lock.yaml: Generated file

Comment thread packages/testing/src/extension.spec.ts Outdated
Comment thread docs/guide/troubleshooting.md
Comment thread docs/guide/troubleshooting.md
Benoit Travers and others added 2 commits July 9, 2026 09:54
Nobody outside this repo consumes @temporal-contract/testing, so the
dependency-to-peer reclassification doesn't warrant a major that would
drag the whole fixed release group to 7.0.0. The group now lands at
6.1.0 (minor, from the qualify helper).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- extension.spec: assert the client connection is closed via afterAll
  instead of a follow-up test that assumed execution order
- troubleshooting docs: add the workflowsPathFromURL import to the two
  worker snippets so they are copy/paste-runnable

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@btravers btravers enabled auto-merge (rebase) July 9, 2026 08:02
Benoit Travers and others added 2 commits July 9, 2026 10:16
unthrown 4 is incompatible with 3: TaggedError now reserves name and
message as payload fields (message is set via Error, not passed as
structured data). Migrated all 14 TaggedError-based error classes in
client and worker to set this.message after super() with a message-free
payload; their public shape (_tag, name, message, typed fields) is
unchanged and covered by the existing error specs.

Bump the catalog (unthrown + @unthrown/vitest to 4.0.0) and the peer
range (^3 -> ^4) in contract, client, and worker. Released as a minor,
not a major: no external consumer is pinned to unthrown@3. Stability
note in the README updated accordingly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Peer Dependency Warnings section listed the Temporal SDK and zod but
omitted unthrown; add it and state that worker/client require it because
its Result/AsyncResult types are part of their public API. README now
tells consumers to install unthrown explicitly (their own code imports
its types) and to pin to v4. Note the v3/v4 incompatibility in both.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@btravers btravers disabled auto-merge July 9, 2026 08:25
The testing package moves @temporalio/client and @temporalio/worker from
dependencies to peerDependencies, which can require consumer action — that's a
minor, not a patch. Bump the audit-fixes changeset accordingly.

Also document qualify()'s flip side: since the wrapper's type/nonRetryable take
precedence, an inner ApplicationFailure's own nonRetryable: true is masked —
pass { nonRetryable: true } (or a custom qualifier) to keep it non-retryable.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@btravers btravers merged commit 420d0b2 into main Jul 9, 2026
10 checks passed
@btravers btravers deleted the audit-fixes branch July 9, 2026 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants