Skip to content

Expose helper resource catalogs and honor shadowed context bindings - #516

Merged
miyaontherelay merged 9 commits into
mainfrom
relayflow/flows-software-garden-22d463a6
Sep 25, 2026
Merged

miyaontherelay merged 9 commits into
mainfrom
relayflow/flows-software-garden-22d463a6

Conversation

@agent-relay-code

@agent-relay-code agent-relay-code Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

GitLab writeback parity has landed in the pinned adapter catalog, so this PR no
longer installs a partial-provider refusal. Instead it rebases the useful part
of the original work onto current main:

  • generated provider metadata publishes each provider's exact sorted adapter
    resources, including GitLab issues, merge requests, refs, merge, and close;
  • generated helper files are byte-identical to the pinned source of truth;
  • helper-reference analysis uses Acorn binding shapes, so destructured locals
    and object/class method parameters named like the flow context do not cause
    false mount refusals;
  • the hosted extension allowlist pins the reviewed byte hash of the regenerated
    Surface runtime.

The obsolete partial-GitLab runtime/preflight machinery is removed by the
current-main merge. This also removes the helper-preflight.ts reads that were
incompatible with the published @relayflows/surface@2.0.22 catalog type; the
SDK now builds against its current pinned Surface package.

Deterministic regressions

  • generated catalog entries are sorted; unsupported providers have no
    resources; GitLab's exact current resource list is pinned;
  • destructured object/array locals and object/class method parameters do not
    register as outer helper references;
  • a real outer reference after a shadowing block still requires the provider
    mount.

Verification

npm test --prefix packages/surface
  10 files passed, 53 tests passed

npx vitest run tests/helper-reference.test.ts tests/helpers-fanout.test.ts
  2 files passed, 120 tests passed

npx vitest run tests/helper-reference.test.ts tests/helpers-fanout.test.ts \
  tests/hosted-extension-isolation.test.ts \
  tests/hosted-extension-protocol.test.ts \
  tests/babysitter-native-extension.test.ts
  5 files passed, 207 tests passed

npm run typecheck --prefix packages/sdk
npm run typecheck:tests --prefix packages/sdk
  passed

bash scripts/surface-package-gate.sh
  HELPERS_GENERATED_OK
  PACKED_RUNTIME_OK
  PACKED_RUNTIME_REFUSAL_OK
  PACKED_TYPESCRIPT_OK
  authored-flow: 1 file passed, 34 tests passed

The explicit historical @relayflows/surface@2.0.22 probe emits none of the
reported helper-preflight TS2367/TS2339/TS2345 diagnostics. A complete current
SDK build against that historical package is not expected to pass because main
now consumes additional, unrelated Surface APIs and pins 2.0.31.

Refs #507


Note

Medium Risk
Shadowing-aware helper detection changes which integrations preflight and flowRequirements demand; incorrect scope logic could under- or over-require mounts, while catalog fields are additive metadata.

Overview
This PR adds inspectable helper provider metadata and fixes false mount refusals when flow bodies shadow the context parameter.

Generated catalog: generate-helpers.mjs now emits a sorted resources list per provider (from the pinned adapter writeback catalog) next to supported, including GitLab’s full current set (issues, merge-requests, refs, merge, close-merge-request, etc.). Unsupported providers get empty resources. Docs and a snapshot test lock sorting, empty unsupported lists, and GitLab parity. The hosted extension sandbox SHA256 pin for helpers/providers.js is updated to match the regenerated file.

Preflight / requirements: helperNamespacesUsed replaces a blind AST walk with walkReferences, which tracks when f (or the flow root name) is shadowed by destructuring, nested method parameters, lexical blocks, catch params, or function-scoped var—so inner f.gitlab access no longer demands a GitLab mount the outer flow never uses. Real outer references after a shadowing block still require mounts. New tests cover those shapes for both preflight and flowRequirements.

Reviewed by Cursor Bugbot for commit 28c46e4. Bugbot is set up for automated code reviews on this repo. Configure here.

…talog

f.gitlab carries comments and discussions; f.github carries issues, pull
requests, reviews, refs, merge and close-pull-request. The catalog marked
both `supported: true`, so the only way to learn the difference was to reach
for `f.gitlab.issues` and read `undefined is not a function` — or to dump the
writeback catalog before writing a line. A GitLab-sourced flow shelled out to
`glab` for every read as a result.

Parity is upstream work. What is fixed here is the silence: `supported` now
distinguishes `'partial'` from full, the generator carries the resources each
provider actually dispatches and the note that says what a partial omits, and
every layer an author can reach the gap through refuses by name — `flows
check` statically, the surface's property guard for a computed name, both
worded by one function and neither touching the provider to refuse.

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: fa25e54f-8947-4569-a362-eb8d4ff8ddd8

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…ent on code it never read

The refusal for a member `f.gitlab` does not carry was reaching for surface
exports that the pinned, published surface does not ship, and was reading
text that is not a member access as one.

- The SDK no longer imports `unsupportedHelperMemberMessage` or
  `UnsupportedHelperMemberError`. Both are unreleased, and this source is
  installed against a published surface in the schema `validate` job, where a
  missing named export fails the whole module at load — before preflight can
  run. The wording is restated locally and pinned equal to the surface's in
  test; the envelope remap matches `error.name`, which is also correct across
  the realm boundary an authored flow file's own surface copy creates.

- Static inspection now admits every member the runtime guard still resolves.
  The guard refuses only what the bound object lacks and is neither `then` nor
  `toJSON`, so `f.gitlab.hasOwnProperty('comments')` returns `true` at run
  time; `flows check` must not reject feature detection that works.

- A regular-expression literal is blanked with the other data literals, so
  `/f.gitlab.issues/.test(line)` — which inspects text and reaches no helper —
  no longer refuses. Ambiguous `/` resolves to "regex", which can only
  withdraw a static refusal and leave the runtime guard to make it.

- A body that binds the context parameter's name again is left to the runtime
  guard. Renaming a local callback parameter cannot decide whether a flow is
  admitted, and an inner `f` need not be the flow context at all.

The last three can only withdraw refusals, never invent them; the runtime
guard remains the backstop for everything they decline to judge.

Co-Authored-By: Claude <noreply@anthropic.com>
@agent-relay-code
agent-relay-code Bot marked this pull request as draft September 20, 2026 17:53
@agent-relay-code

Copy link
Copy Markdown
Contributor Author

Relayflow: the adversarial review did not pass. This branch is not approved: the flow stopped here and did not mark it ready to merge.

Review of PR #516

Reviewed head: 889198d0cf4b773aa08aadefacd8b752711df2a4.
PR: #516

Changes requested. review.clean is not created. The ticket permits the partial-support resolution, but two issues remain in the follow-up commit.

1. [P1] Compile the SDK against its pinned published surface

Location: packages/sdk/src/helper-preflight.ts:29-37.

Removing the new named imports fixes the module-load failure, but the SDK still cannot compile against its declared dependency, @relayflows/surface@2.0.22. That registry package types supported as boolean and has no resources or note. The new comparison and property accesses produce TS2367, TS2339 and TS2345. A normal SDK build using the declared dependency therefore fails. The local dependency is a symlink to ../../../surface, which hides the mismatch.

I copied the current SDK source, package.json and tsconfig.json into /tmp/gitlab-review-head/clean-sdk, linked its other installed dependencies, and extracted the registry surface tarball into its node_modules. Compilation fails with the four diagnostics captured below. Replacing only this copied helper-preflight.ts with the base version makes that compilation exit 0; the copied head file was restored afterwards. This is a controlled file comparison, not a full base-suite run.

Ship and pin compatible surface types, or explicitly normalize the old/new catalog shapes before reading the optional new fields. Add coverage that compiles with the published dependency rather than only the local surface. The now-green schema validation job runs Bun source tests and does not demonstrate this TypeScript build succeeds.

2. [P2] Do not refuse accesses on destructured locals or method parameters

Location: packages/sdk/src/source-scan.ts:159-180.

The rebinding detector handles simple declarations and function/arrow/catch parameters, but misses destructured declarations and method parameters. Both of these valid bodies return 42 without accessing a GitLab helper:

(f) => { { const { f } = { f: { gitlab: { issues: 42 } } }; return f.gitlab.issues; } }
(f) => ({ read(f) { return f.gitlab.issues; } }).read({ gitlab: { issues: 42 } })

With the GitLab mount fact satisfied, preflight rejects both as helper_provider.unsupported. The previous shadowing finding therefore remains partially unresolved: renaming a local parameter can still determine whether a valid flow is admitted. Track bindings with syntax-aware analysis, or conservatively decline static refusal on binding forms the scanner cannot establish. Add regressions for destructuring and object/class method parameters.

Scope and limits

Reviewed all 16 changed files, the previous local review, and the PR discussion, inline comments and submitted reviews via paginated GitHub API requests. At the captured snapshot there is one CodeRabbit skipped-review notice, no inline comments, and no submitted reviews. The PR description still describes the original commit's scanner and tests; it is not evidence for the follow-up fixes.

The follow-up covers the earlier inherited-member and simple regex reproductions with regression tests. The package compatibility problem persists at compilation, and shadowing remains incomplete as described above. No production source, generated file, test gate, or docs/evidence file was changed during this review. No live GitLab API verification is claimed. No PR comments were posted.

Affected-package verification

npm test --prefix packages/surface exited 0: 55 tests passed. npm run typecheck:regressions --prefix packages/surface exited 0. The full command outputs are below.

npm test --prefix packages/sdk exited 1: 7 failed files, 148 passed, 3 skipped; 41 failed tests, 2364 passed, 25 skipped, and 1 unhandled error. Its output includes passes for the 12 partial-support tests, 96 helper-fanout tests and 6 authored-helper tests. Failures include the Bun version requirement, unavailable binaries at hardcoded kernel paths, analyzer execution and flow-handle assertions. These full-suite failures are observations, not established PR regressions: I did not run the full base suite. The isolated TypeScript failure in finding 1 has a separate controlled comparison.

Reproduction source

The probe executes harmless data-only bodies and calls preflight with a satisfied mount; no provider is contacted.

import { preflightHelpers } from '/home/daytona/.relayflow-v2-supervisor/durable/repository/packages/sdk/src/helper-preflight.ts';
import { createHelpers } from '/home/daytona/.relayflow-v2-supervisor/durable/repository/packages/surface/dist/runtime.js';
const facts = {providers:{gitlab:{mount:true,mock:false}}};
const cases = {
 destructured: '(f) => { { const { f } = { f: {gitlab:{issues:42}} }; return f.gitlab.issues; } }',
 method: '(f) => ({ read(f) { return f.gitlab.issues; } }).read({gitlab:{issues:42}})',
 namespacePrefix: '(f) => { f.gitlabExtra = {issues:42}; return f.gitlabExtra.issues; }',
 regexAfterReturnNewline: '(f) => { return\n /f.gitlab.issues/.test("x"); }',
};
const helpers = createHelpers(() => {throw Error('unexpected dispatch')});
for (const [name,source] of Object.entries(cases)) {
 try {const body = new Function(`return ${source}`)(); console.log(JSON.stringify({name, runtime:body({...helpers}), preflight:preflightHelpers({body},facts)}));} catch(e) { console.log(name,String(e));}
}

Captured command

bun /tmp/gitlab-review-head/probe.ts

Exit code: 0. Captured stdout/stderr:

{"name":"destructured","runtime":42,"preflight":{"ok":false,"gates":[],"resolutions":[],"diagnostics":[{"severity":"refusal","kind":"helper_provider.unsupported","message":"f.gitlab.issues is unavailable; available resources: comments, discussions. Comments and discussions only. Issue list/read/create and merge-request list/read/create are unavailable through f.gitlab."}]}}
{"name":"method","runtime":42,"preflight":{"ok":false,"gates":[],"resolutions":[],"diagnostics":[{"severity":"refusal","kind":"helper_provider.unsupported","message":"f.gitlab.issues is unavailable; available resources: comments, discussions. Comments and discussions only. Issue list/read/create and merge-request list/read/create are unavailable through f.gitlab."}]}}
{"name":"namespacePrefix","runtime":42,"preflight":{"ok":true,"gates":[],"resolutions":[],"diagnostics":[]}}
{"name":"regexAfterReturnNewline","preflight":{"ok":true,"gates":[],"resolutions":[],"diagnostics":[]}}

Captured command

packages/sdk/node_modules/.bin/tsc --noEmit -p /tmp/gitlab-review-head/clean-sdk/tsconfig.json

Exit code: 2. Captured stdout/stderr:

../../../../../tmp/gitlab-review-head/clean-sdk/src/helper-preflight.ts(29,21): error TS2367: This comparison appears to be unintentional because the types 'boolean' and 'string' have no overlap.
../../../../../tmp/gitlab-review-head/clean-sdk/src/helper-preflight.ts(30,64): error TS2339: Property 'resources' does not exist on type 'never'.
../../../../../tmp/gitlab-review-head/clean-sdk/src/helper-preflight.ts(36,70): error TS2339: Property 'resources' does not exist on type '{ readonly provider: "asana"; readonly namespace: "asana"; readonly mockEnv: "RELAYFLOWS_ASANA_MOCK"; readonly supported: true; } | { readonly provider: "azure-blob"; readonly namespace: "azureBlob"; readonly mockEnv: "RELAYFLOWS_AZURE_BLOB_MOCK"; readonly supported: true; } | ... 37 more ... | { ...; }'.
  Property 'resources' does not exist on type '{ readonly provider: "asana"; readonly namespace: "asana"; readonly mockEnv: "RELAYFLOWS_ASANA_MOCK"; readonly supported: true; }'.
../../../../../tmp/gitlab-review-head/clean-sdk/src/helper-preflight.ts(37,11): error TS2345: Argument of type 'unknown' is not assignable to parameter of type 'string | undefined'.

Captured command

git show origin/main:packages/sdk/src/helper-preflight.ts > /tmp/gitlab-review-head/clean-sdk/src/helper-preflight.ts
packages/sdk/node_modules/.bin/tsc --noEmit -p /tmp/gitlab-review-head/clean-sdk/tsconfig.json

Exit code: 0. Captured stdout/stderr (empty):


Captured command

npm test --prefix packages/surface

Exit code: 0. Captured stdout/stderr:


> @relayflows/surface@2.0.22 test
> bun run build && tsc -p tsconfig.test.json && vitest run

$ tsc

 RUN  v2.1.9 /home/daytona/.relayflow-v2-supervisor/durable/repository/packages/surface

 ✓ tests/helper-support.test.ts (9 tests) 39ms
 ✓ tests/flow.test.ts (20 tests) 44ms
 ✓ tests/slack-block-kit.test.ts (5 tests) 3ms
 ✓ tests/triggers-all-providers.test.ts (4 tests) 85ms
 ✓ tests/provider-triggers.test.ts (3 tests) 5ms
 ✓ tests/triggers.test.ts (4 tests) 8ms
 ✓ tests/triggers-github-events.test.ts (1 test) 3ms
 ✓ tests/declined.test.ts (1 test) 2ms
 ✓ tests/helpers.snapshot.test.ts (1 test) 322ms
   ✓ regenerates helpers byte-identically from the pinned adapter 321ms
 ✓ tests/schedule.test.ts (7 tests) 8354ms
   ✓ schedule.cron > measures a cron's longest quiet period so a silence budget can be declared honestly 8309ms

 Test Files  10 passed (10)
      Tests  55 passed (55)
   Start at  17:48:47
   Duration  8.89s (transform 749ms, setup 0ms, collect 1.82s, tests 8.86s, environment 1ms, prepare 697ms)


Captured command

npm run typecheck:regressions --prefix packages/surface

Exit code: 0. Captured stdout/stderr:


> @relayflows/surface@2.0.22 typecheck:regressions
> tsc -p ../../regressions/tsconfig.json && tsc -p tsconfig.test.json && node scripts/check-generated-helpers.mjs

HELPERS_GENERATED_OK airtable.ts, asana.ts, azure-blob.ts, box.ts, calendly.ts, clickup.ts, clients.ts, cloudflare.ts, confluence.ts, daytona.ts, docker-hub.ts, dropbox.ts, fathom.ts, gcp.ts, gcs.ts, github.ts, gitlab.ts, gmail.ts, google-calendar.ts, google-drive.ts, granola.ts, hubspot.ts, index.ts, intercom.ts, jira.ts, linear.ts, mailgun.ts, mixpanel.ts, neon.ts, notion.ts, onedrive.ts, pipedrive.ts, postgres.ts, posthog.ts, providers.ts, ramp.ts, recall.ts, reddit.ts, redis.ts, s3.ts, salesforce.ts, segment.ts, sendgrid.ts, sharepoint.ts, shopify.ts, shortcut.ts, slack.ts, stripe.ts, teams.ts, telegram.ts, webhook-server.ts, x.ts, zendesk.ts

Captured command

gh pr checks 516

Exit code: 0. Captured stdout/stderr:

npm	skipping	0	https://github.com/AgentWorkforce/flows/actions/runs/35527025061/job/106121038583	
pages	skipping	0	https://github.com/AgentWorkforce/flows/actions/runs/35527025061/job/106121038980	
guard	pass	7s	https://github.com/AgentWorkforce/flows/actions/runs/35527023338/job/106120860236	
validate	pass	12s	https://github.com/AgentWorkforce/flows/actions/runs/35527025061/job/106120863758	
linux-x64-artifact	pending	0	https://github.com/AgentWorkforce/flows/actions/runs/35527025077/job/106120863891	
packed-consumer	pass	54s	https://github.com/AgentWorkforce/flows/actions/runs/35527025064/job/106120864016	
Cursor Bugbot	pending	0	https://cursor.com/docs/bugbot	
CodeRabbit	pass	0		Review skipped: bot user not eligible for review

Captured command

gh api --paginate repos/AgentWorkforce/flows/issues/516/comments

Exit code: 0. Captured stdout/stderr:

[{"url":"https://api.github.com/repos/AgentWorkforce/flows/issues/comments/5751348737","html_url":"https://github.com/AgentWorkforce/flows/pull/516#issuecomment-5751348737","issue_url":"https://api.github.com/repos/AgentWorkforce/flows/issues/516","id":5751348737,"node_id":"IC_kwDOUF0ysM8AAAABVs6eAQ","user":{"login":"coderabbitai[bot]","id":136622811,"node_id":"BOT_kgDOCCSy2w","avatar_url":"https://avatars.githubusercontent.com/in/347564?v=4","gravatar_id":"","url":"https://api.github.com/users/coderabbitai%5Bbot%5D","html_url":"https://github.com/apps/coderabbitai","followers_url":"https://api.github.com/users/coderabbitai%5Bbot%5D/followers","following_url":"https://api.github.com/users/coderabbitai%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/coderabbitai%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/coderabbitai%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coderabbitai%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/coderabbitai%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/coderabbitai%5Bbot%5D/repos","events_url":"https://api.github.com/users/coderabbitai%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/coderabbitai%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"created_at":"2026-09-20T17:15:35Z","updated_at":"2026-09-20T17:48:19Z","body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- This is an auto-generated comment: skip review by coderabbit.ai -->\n\n> [!IMPORTANT]\n> ## Review skipped\n> \n> Bot user detected.\n> \n> To trigger a single review, invoke the `@coderabbitai review` command.\n> \n> <details>\n> <summary>⚙️ Run configuration</summary>\n> \n> **Configuration used**: Organization UI\n> \n> **Review profile**: CHILL\n> \n> **Plan**: Advanced\n> \n> **Run ID**: `b77994bb-ff6b-4b4e-ab48-899670bc7b92`\n> \n> </details>\n> \n> You can disable this status message by setting the `reviews.review_status` to `false` in the CodeRabbit configuration file.\n> \n> Use the checkbox below for a quick retry:\n> - [ ] <!-- {\"checkboxId\":\"e9bb8d72-00e8-4f67-9cb2-caf3b22574fe\"} --> 🔍 Trigger review\n\n<!-- end of auto-generated comment: skip review by coderabbit.ai -->\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=AgentWorkforce/flows&utm_content=516)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n\n<sub>Comment `@coderabbitai help` to get the list of available commands.</sub>\n\n<!-- tips_end -->","author_association":"NONE","reactions":{"url":"https://api.github.com/repos/AgentWorkforce/flows/issues/comments/5751348737/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"performed_via_github_app":{"id":347564,"client_id":"Iv1.6aaafe4fe882736b","slug":"coderabbitai","node_id":"A_kwHOB96YWc4ABU2s","owner":{"login":"coderabbitai","id":132028505,"node_id":"O_kgDOB96YWQ","avatar_url":"https://avatars.githubusercontent.com/u/132028505?v=4","gravatar_id":"","url":"https://api.github.com/users/coderabbitai","html_url":"https://github.com/coderabbitai","followers_url":"https://api.github.com/users/coderabbitai/followers","following_url":"https://api.github.com/users/coderabbitai/following{/other_user}","gists_url":"https://api.github.com/users/coderabbitai/gists{/gist_id}","starred_url":"https://api.github.com/users/coderabbitai/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coderabbitai/subscriptions","organizations_url":"https://api.github.com/users/coderabbitai/orgs","repos_url":"https://api.github.com/users/coderabbitai/repos","events_url":"https://api.github.com/users/coderabbitai/events{/privacy}","received_events_url":"https://api.github.com/users/coderabbitai/received_events","type":"Organization","user_view_type":"public","site_admin":false},"name":"coderabbitai","description":"# Transforming Code Reviews with AI\r\n\r\n## Features\r\n\r\n**Automated Reviews**: Continuous reviews of the pull requests including incremental commits. \r\n\r\n**Summarization**: Generates high-level summary and a technical walkthrough of the PR changes. \r\n\r\n**Line-by-line review**: Provides line-by-line suggestions committable with one click.\r\n\r\n**Codebase verification**:  Verifies the impact on the overall codebase and identifies missing changes.\r\n\r\n**Insights into your code**:  Ask any questions on your codebase within the pull request \r\n\r\n**Chat about your code** : Chat with the bot around your code. The more you chat, the smarter it gets.\r\n\r\n**Issue Validation**:  Validates the PR against the linked issues and identifies other related issues \r\n\r\n\r\n\r\n","external_url":"https://coderabbit.ai?utm_source=cr_app&utm_medium=github","html_url":"https://github.com/apps/coderabbitai","created_at":"2023-06-14T15:47:27Z","updated_at":"2026-09-20T03:49:19Z","permissions":{"actions":"read","checks":"write","contents":"write","discussions":"read","issues":"write","members":"read","merge_queues":"read","metadata":"read","pull_requests":"write","statuses":"write"},"events":["issues","issue_comment","label","membership","merge_group","organization","pull_request","pull_request_review","pull_request_review_comment","pull_request_review_thread","release","repository","team"]},"minimized":null}]

Captured command

gh api --paginate repos/AgentWorkforce/flows/pulls/516/comments

Exit code: 0. Captured stdout/stderr:

[]

Captured command

gh api --paginate repos/AgentWorkforce/flows/pulls/516/reviews

Exit code: 0. Captured stdout/stderr:

[]

Reproducing the dependency-isolated TypeScript check

The temporary SDK keeps all other installed dependencies fixed and changes only surface resolution from the local symlink to the registry artifact. From the repository root, use a fresh temporary directory (the path below was used for the captured run):

npm pack @relayflows/surface@2.0.22 --pack-destination /tmp/gitlab-review-head/registry

The source-copy and dependency setup used for the captured check:

from pathlib import Path
import shutil, tarfile
repo=Path.cwd(); target=Path('/tmp/gitlab-review-head/clean-sdk'); target.mkdir(exist_ok=True)
shutil.copytree(repo/'packages/sdk/src',target/'src',dirs_exist_ok=True)
shutil.copy(repo/'packages/sdk/package.json',target/'package.json')
shutil.copy(repo/'packages/sdk/tsconfig.json',target/'tsconfig.json')
deps=target/'node_modules'; deps.mkdir(exist_ok=True)
for p in (repo/'packages/sdk/node_modules').iterdir():
 if p.name=='@relayflows':
  (deps/p.name).mkdir(exist_ok=True)
  for child in p.iterdir():
   if child.name!='surface': (deps/p.name/child.name).symlink_to(child.resolve())
 else: (deps/p.name).symlink_to(p.resolve())
surface=deps/'@relayflows/surface'; surface.mkdir(exist_ok=True)
with tarfile.open('/tmp/gitlab-review-head/registry/relayflows-surface-2.0.22.tgz') as tar:
 for m in tar.getmembers():
  if m.name.startswith('package/'):
   m.name=m.name[len('package/'):]; tar.extract(m,surface,filter='data')

Registry pack command captured output (exit 0):

npm notice
npm notice 📦  @relayflows/surface@2.0.22
npm notice Tarball Contents
npm notice 2.9kB README.md
npm notice 2.5kB dist/cloud.d.ts
npm notice 2.3kB dist/cloud.d.ts.map
npm notice 44B dist/cloud.js
npm notice 102B dist/cloud.js.map
npm notice 938B dist/completion.d.ts
npm notice 463B dist/completion.d.ts.map
npm notice 711B dist/completion.js
npm notice 458B dist/completion.js.map
npm notice 3.3kB dist/context.d.ts
npm notice 2.0kB dist/context.d.ts.map
npm notice 46B dist/context.js
npm notice 106B dist/context.js.map
npm notice 1.3kB dist/effect-transport.d.ts
npm notice 1.4kB dist/effect-transport.d.ts.map
npm notice 2.0kB dist/effect-transport.js
npm notice 2.3kB dist/effect-transport.js.map
npm notice 2.6kB dist/flow.d.ts
npm notice 2.5kB dist/flow.d.ts.map
npm notice 9.9kB dist/flow.js
npm notice 10.1kB dist/flow.js.map
npm notice 3.3kB dist/helper-clients.d.ts
npm notice 944B dist/helper-clients.d.ts.map
npm notice 1.7kB dist/helper-clients.js
npm notice 1.6kB dist/helper-clients.js.map
npm notice 265B dist/helpers/airtable.d.ts
npm notice 281B dist/helpers/airtable.d.ts.map
npm notice 319B dist/helpers/airtable.js
npm notice 293B dist/helpers/airtable.js.map
npm notice 333B dist/helpers/asana.d.ts
npm notice 348B dist/helpers/asana.d.ts.map
npm notice 368B dist/helpers/asana.js
npm notice 329B dist/helpers/asana.js.map
npm notice 358B dist/helpers/azure-blob.d.ts
npm notice 357B dist/helpers/azure-blob.d.ts.map
npm notice 390B dist/helpers/azure-blob.js
npm notice 340B dist/helpers/azure-blob.js.map
npm notice 321B dist/helpers/box.d.ts
npm notice 342B dist/helpers/box.d.ts.map
npm notice 358B dist/helpers/box.js
npm notice 323B dist/helpers/box.js.map
npm notice 351B dist/helpers/calendly.d.ts
npm notice 354B dist/helpers/calendly.d.ts.map
npm notice 383B dist/helpers/calendly.js
npm notice 336B dist/helpers/calendly.js.map
npm notice 345B dist/helpers/clickup.d.ts
npm notice 352B dist/helpers/clickup.d.ts.map
npm notice 378B dist/helpers/clickup.js
npm notice 334B dist/helpers/clickup.js.map
npm notice 175B dist/helpers/clients.d.ts
npm notice 243B dist/helpers/clients.d.ts.map
npm notice 1.9kB dist/helpers/clients.js
npm notice 1.5kB dist/helpers/clients.js.map
npm notice 363B dist/helpers/cloudflare.d.ts
npm notice 364B dist/helpers/cloudflare.d.ts.map
npm notice 393B dist/helpers/cloudflare.js
npm notice 344B dist/helpers/cloudflare.js.map
npm notice 363B dist/helpers/confluence.d.ts
npm notice 364B dist/helpers/confluence.d.ts.map
npm notice 393B dist/helpers/confluence.js
npm notice 344B dist/helpers/confluence.js.map
npm notice 345B dist/helpers/daytona.d.ts
npm notice 352B dist/helpers/daytona.d.ts.map
npm notice 378B dist/helpers/daytona.js
npm notice 334B dist/helpers/daytona.js.map
npm notice 270B dist/helpers/docker-hub.d.ts
npm notice 285B dist/helpers/docker-hub.d.ts.map
npm notice 324B dist/helpers/docker-hub.js
npm notice 297B dist/helpers/docker-hub.js.map
npm notice 345B dist/helpers/dropbox.d.ts
npm notice 352B dist/helpers/dropbox.d.ts.map
npm notice 378B dist/helpers/dropbox.js
npm notice 334B dist/helpers/dropbox.js.map
npm notice 257B dist/helpers/fathom.d.ts
npm notice 277B dist/helpers/fathom.d.ts.map
npm notice 313B dist/helpers/fathom.js
npm notice 289B dist/helpers/fathom.js.map
npm notice 245B dist/helpers/gcp.d.ts
npm notice 269B dist/helpers/gcp.d.ts.map
npm notice 304B dist/helpers/gcp.js
npm notice 280B dist/helpers/gcp.js.map
npm notice 321B dist/helpers/gcs.d.ts
npm notice 342B dist/helpers/gcs.d.ts.map
npm notice 358B dist/helpers/gcs.js
npm notice 323B dist/helpers/gcs.js.map
npm notice 335B dist/helpers/github.d.ts
npm notice 350B dist/helpers/github.d.ts.map
npm notice 369B dist/helpers/github.js
npm notice 332B dist/helpers/github.js.map
npm notice 339B dist/helpers/gitlab.d.ts
npm notice 350B dist/helpers/gitlab.d.ts.map
npm notice 373B dist/helpers/gitlab.js
npm notice 332B dist/helpers/gitlab.js.map
npm notice 333B dist/helpers/gmail.d.ts
npm notice 348B dist/helpers/gmail.d.ts.map
npm notice 368B dist/helpers/gmail.js
npm notice 329B dist/helpers/gmail.js.map
npm notice 388B dist/helpers/google-calendar.d.ts
npm notice 374B dist/helpers/google-calendar.d.ts.map
npm notice 415B dist/helpers/google-calendar.js
npm notice 356B dist/helpers/google-calendar.js.map
npm notice 370B dist/helpers/google-drive.d.ts
npm notice 368B dist/helpers/google-drive.d.ts.map
npm notice 400B dist/helpers/google-drive.js
npm notice 348B dist/helpers/google-drive.js.map
npm notice 345B dist/helpers/granola.d.ts
npm notice 352B dist/helpers/granola.d.ts.map
npm notice 378B dist/helpers/granola.js
npm notice 334B dist/helpers/granola.js.map
npm notice 345B dist/helpers/hubspot.d.ts
npm notice 352B dist/helpers/hubspot.d.ts.map
npm notice 378B dist/helpers/hubspot.js
npm notice 334B dist/helpers/hubspot.js.map
npm notice 6.7kB dist/helpers/index.d.ts
npm notice 6.0kB dist/helpers/index.d.ts.map
npm notice 5.1kB dist/helpers/index.js
npm notice 4.2kB dist/helpers/index.js.map
npm notice 351B dist/helpers/intercom.d.ts
npm notice 354B dist/helpers/intercom.d.ts.map
npm notice 383B dist/helpers/intercom.js
npm notice 336B dist/helpers/intercom.js.map
npm notice 327B dist/helpers/jira.d.ts
npm notice 346B dist/helpers/jira.d.ts.map
npm notice 363B dist/helpers/jira.js
npm notice 327B dist/helpers/jira.js.map
npm notice 339B dist/helpers/linear.d.ts
npm notice 350B dist/helpers/linear.d.ts.map
npm notice 373B dist/helpers/linear.js
npm notice 332B dist/helpers/linear.js.map
npm notice 345B dist/helpers/mailgun.d.ts
npm notice 352B dist/helpers/mailgun.d.ts.map
npm notice 378B dist/helpers/mailgun.js
npm notice 334B dist/helpers/mailgun.js.map
npm notice 351B dist/helpers/mixpanel.d.ts
npm notice 354B dist/helpers/mixpanel.d.ts.map
npm notice 383B dist/helpers/mixpanel.js
npm notice 336B dist/helpers/mixpanel.js.map
npm notice 249B dist/helpers/neon.d.ts
npm notice 273B dist/helpers/neon.d.ts.map
npm notice 307B dist/helpers/neon.js
npm notice 284B dist/helpers/neon.js.map
npm notice 335B dist/helpers/notion.d.ts
npm notice 350B dist/helpers/notion.d.ts.map
npm notice 369B dist/helpers/notion.js
npm notice 332B dist/helpers/notion.js.map
npm notice 351B dist/helpers/onedrive.d.ts
npm notice 354B dist/helpers/onedrive.d.ts.map
npm notice 383B dist/helpers/onedrive.js
npm notice 336B dist/helpers/onedrive.js.map
npm notice 357B dist/helpers/pipedrive.d.ts
npm notice 355B dist/helpers/pipedrive.d.ts.map
npm notice 388B dist/helpers/pipedrive.js
npm notice 338B dist/helpers/pipedrive.js.map
npm notice 351B dist/helpers/postgres.d.ts
npm notice 354B dist/helpers/postgres.d.ts.map
npm notice 383B dist/helpers/postgres.js
npm notice 336B dist/helpers/postgres.js.map
npm notice 261B dist/helpers/posthog.d.ts
npm notice 279B dist/helpers/posthog.d.ts.map
npm notice 316B dist/helpers/posthog.js
npm notice 291B dist/helpers/posthog.js.map
npm notice 7.7kB dist/helpers/providers.d.ts
npm notice 403B dist/helpers/providers.d.ts.map
npm notice 7.6kB dist/helpers/providers.js
npm notice 5.0kB dist/helpers/providers.js.map
npm notice 479B dist/helpers/ramp.d.ts
npm notice 403B dist/helpers/ramp.d.ts.map
npm notice 432B dist/helpers/ramp.js
npm notice 409B dist/helpers/ramp.js.map
npm notice 339B dist/helpers/recall.d.ts
npm notice 350B dist/helpers/recall.d.ts.map
npm notice 373B dist/helpers/recall.js
npm notice 332B dist/helpers/recall.js.map
npm notice 339B dist/helpers/reddit.d.ts
npm notice 350B dist/helpers/reddit.d.ts.map
npm notice 373B dist/helpers/reddit.js
npm notice 332B dist/helpers/reddit.js.map
npm notice 333B dist/helpers/redis.d.ts
npm notice 348B dist/helpers/redis.d.ts.map
npm notice 368B dist/helpers/redis.js
npm notice 329B dist/helpers/redis.js.map
npm notice 315B dist/helpers/s3.d.ts
npm notice 340B dist/helpers/s3.d.ts.map
npm notice 353B dist/helpers/s3.js
npm notice 321B dist/helpers/s3.js.map
npm notice 363B dist/helpers/salesforce.d.ts
npm notice 364B dist/helpers/salesforce.d.ts.map
npm notice 393B dist/helpers/salesforce.js
npm notice 344B dist/helpers/salesforce.js.map
npm notice 261B dist/helpers/segment.d.ts
npm notice 279B dist/helpers/segment.d.ts.map
npm notice 316B dist/helpers/segment.js
npm notice 291B dist/helpers/segment.js.map
npm notice 351B dist/helpers/sendgrid.d.ts
npm notice 354B dist/helpers/sendgrid.d.ts.map
npm notice 383B dist/helpers/sendgrid.js
npm notice 336B dist/helpers/sendgrid.js.map
npm notice 363B dist/helpers/sharepoint.d.ts
npm notice 364B dist/helpers/sharepoint.d.ts.map
npm notice 393B dist/helpers/sharepoint.js
npm notice 344B dist/helpers/sharepoint.js.map
npm notice 261B dist/helpers/shopify.d.ts
npm notice 279B dist/helpers/shopify.d.ts.map
npm notice 316B dist/helpers/shopify.js
npm notice 291B dist/helpers/shopify.js.map
npm notice 351B dist/helpers/shortcut.d.ts
npm notice 354B dist/helpers/shortcut.d.ts.map
npm notice 383B dist/helpers/shortcut.js
npm notice 336B dist/helpers/shortcut.js.map
npm notice 822B dist/helpers/slack.d.ts
npm notice 850B dist/helpers/slack.d.ts.map
npm notice 179B dist/helpers/slack.js
npm notice 137B dist/helpers/slack.js.map
npm notice 335B dist/helpers/stripe.d.ts
npm notice 350B dist/helpers/stripe.d.ts.map
npm notice 369B dist/helpers/stripe.js
npm notice 332B dist/helpers/stripe.js.map
npm notice 333B dist/helpers/teams.d.ts
npm notice 348B dist/helpers/teams.d.ts.map
npm notice 368B dist/helpers/teams.js
npm notice 329B dist/helpers/teams.js.map
npm notice 351B dist/helpers/telegram.d.ts
npm notice 354B dist/helpers/telegram.d.ts.map
npm notice 383B dist/helpers/telegram.js
npm notice 336B dist/helpers/telegram.js.map
npm notice 286B dist/helpers/webhook-server.d.ts
npm notice 296B dist/helpers/webhook-server.d.ts.map
npm notice 336B dist/helpers/webhook-server.js
npm notice 307B dist/helpers/webhook-server.js.map
npm notice 237B dist/helpers/x.d.ts
npm notice 265B dist/helpers/x.d.ts.map
npm notice 298B dist/helpers/x.js
npm notice 276B dist/helpers/x.js.map
npm notice 345B dist/helpers/zendesk.d.ts
npm notice 352B dist/helpers/zendesk.d.ts.map
npm notice 378B dist/helpers/zendesk.js
npm notice 334B dist/helpers/zendesk.js.map
npm notice 1.6kB dist/index.d.ts
npm notice 1.3kB dist/index.d.ts.map
npm notice 434B dist/index.js
npm notice 426B dist/index.js.map
npm notice 866B dist/memory.d.ts
npm notice 722B dist/memory.d.ts.map
npm notice 45B dist/memory.js
npm notice 104B dist/memory.js.map
npm notice 321B dist/plugin-contract.d.ts
npm notice 363B dist/plugin-contract.d.ts.map
npm notice 54B dist/plugin-contract.js
npm notice 122B dist/plugin-contract.js.map
npm notice 758B dist/provider-trigger.d.ts
npm notice 691B dist/provider-trigger.d.ts.map
npm notice 808B dist/provider-trigger.js
npm notice 817B dist/provider-trigger.js.map
npm notice 497B dist/runtime.d.ts
npm notice 478B dist/runtime.d.ts.map
npm notice 345B dist/runtime.js
npm notice 362B dist/runtime.js.map
npm notice 4.0kB dist/schedule.d.ts
npm notice 1.5kB dist/schedule.d.ts.map
npm notice 12.7kB dist/schedule.js
npm notice 12.1kB dist/schedule.js.map
npm notice 1.5kB dist/slack.d.ts
npm notice 1.3kB dist/slack.d.ts.map
npm notice 784B dist/slack.js
npm notice 907B dist/slack.js.map
npm notice 2.7kB dist/step.d.ts
npm notice 1.2kB dist/step.d.ts.map
npm notice 43B dist/step.js
npm notice 100B dist/step.js.map
npm notice 827B dist/triggers.d.ts
npm notice 690B dist/triggers.d.ts.map
npm notice 2.2kB dist/triggers.js
npm notice 2.2kB dist/triggers.js.map
npm notice 1.3kB dist/triggers/airtable.d.ts
npm notice 299B dist/triggers/airtable.d.ts.map
npm notice 1.1kB dist/triggers/airtable.js
npm notice 1.0kB dist/triggers/airtable.js.map
npm notice 2.3kB dist/triggers/asana.d.ts
npm notice 382B dist/triggers/asana.d.ts.map
npm notice 2.0kB dist/triggers/asana.js
npm notice 1.8kB dist/triggers/asana.js.map
npm notice 525B dist/triggers/azure-blob.d.ts
npm notice 237B dist/triggers/azure-blob.d.ts.map
npm notice 517B dist/triggers/azure-blob.js
npm notice 509B dist/triggers/azure-blob.js.map
npm notice 490B dist/triggers/box.d.ts
npm notice 223B dist/triggers/box.d.ts.map
npm notice 482B dist/triggers/box.js
npm notice 495B dist/triggers/box.js.map
npm notice 1.8kB dist/triggers/calendly.d.ts
npm notice 332B dist/triggers/calendly.d.ts.map
npm notice 1.6kB dist/triggers/calendly.js
npm notice 1.3kB dist/triggers/calendly.js.map
npm notice 1.7kB dist/triggers/clickup.d.ts
npm notice 330B dist/triggers/clickup.d.ts.map
npm notice 1.4kB dist/triggers/clickup.js
npm notice 1.3kB dist/triggers/clickup.js.map
npm notice 1.4kB dist/triggers/cloudflare.d.ts
npm notice 298B dist/triggers/cloudflare.d.ts.map
npm notice 1.3kB dist/triggers/cloudflare.js
npm notice 977B dist/triggers/cloudflare.js.map
npm notice 915B dist/triggers/confluence.d.ts
npm notice 270B dist/triggers/confluence.d.ts.map
npm notice 835B dist/triggers/confluence.js
npm notice 773B dist/triggers/confluence.js.map
npm notice 1.1kB dist/triggers/daytona.d.ts
npm notice 277B dist/triggers/daytona.d.ts.map
npm notice 986B dist/triggers/daytona.js
npm notice 879B dist/triggers/daytona.js.map
npm notice 253B dist/triggers/docker-hub.d.ts
npm notice 215B dist/triggers/docker-hub.d.ts.map
npm notice 293B dist/triggers/docker-hub.js
npm notice 333B dist/triggers/docker-hub.js.map
npm notice 260B dist/triggers/dropbox.d.ts
npm notice 209B dist/triggers/dropbox.d.ts.map
npm notice 300B dist/triggers/dropbox.js
npm notice 327B dist/triggers/dropbox.js.map
npm notice 283B dist/triggers/fathom.d.ts
npm notice 208B dist/triggers/fathom.d.ts.map
npm notice 323B dist/triggers/fathom.js
npm notice 329B dist/triggers/fathom.js.map
npm notice 1.5kB dist/triggers/gcp.d.ts
npm notice 291B dist/triggers/gcp.d.ts.map
npm notice 1.3kB dist/triggers/gcp.js
npm notice 1.1kB dist/triggers/gcp.js.map
npm notice 490B dist/triggers/gcs.d.ts
npm notice 223B dist/triggers/gcs.d.ts.map
npm notice 482B dist/triggers/gcs.js
npm notice 495B dist/triggers/gcs.js.map
npm notice 3.7kB dist/triggers/github.d.ts
npm notice 489B dist/triggers/github.d.ts.map
npm notice 3.4kB dist/triggers/github.js
npm notice 2.9kB dist/triggers/github.js.map
npm notice 6.9kB dist/triggers/gitlab.d.ts
npm notice 787B dist/triggers/gitlab.d.ts.map
npm notice 5.7kB dist/triggers/gitlab.js
npm notice 5.0kB dist/triggers/gitlab.js.map
npm notice 500B dist/triggers/gmail.d.ts
npm notice 227B dist/triggers/gmail.d.ts.map
npm notice 492B dist/triggers/gmail.js
npm notice 499B dist/triggers/gmail.js.map
npm notice 572B dist/triggers/google-calendar.d.ts
npm notice 248B dist/triggers/google-calendar.d.ts.map
npm notice 564B dist/triggers/google-calendar.js
npm notice 531B dist/triggers/google-calendar.js.map
npm notice 535B dist/triggers/google-drive.d.ts
npm notice 241B dist/triggers/google-drive.d.ts.map
npm notice 527B dist/triggers/google-drive.js
npm notice 513B dist/triggers/google-drive.js.map
npm notice 651B dist/triggers/granola.d.ts
npm notice 243B dist/triggers/granola.d.ts.map
npm notice 619B dist/triggers/granola.js
npm notice 597B dist/triggers/granola.js.map
npm notice 2.8kB dist/triggers/hubspot.d.ts
npm notice 423B dist/triggers/hubspot.d.ts.map
npm notice 2.4kB dist/triggers/hubspot.js
npm notice 2.0kB dist/triggers/hubspot.js.map
npm notice 14.8kB dist/triggers/index.d.ts
npm notice 2.2kB dist/triggers/index.d.ts.map
npm notice 15.3kB dist/triggers/index.js
npm notice 10.7kB dist/triggers/index.js.map
npm notice 2.6kB dist/triggers/intercom.d.ts
npm notice 398B dist/triggers/intercom.d.ts.map
npm notice 2.2kB dist/triggers/intercom.js
npm notice 1.9kB dist/triggers/intercom.js.map
npm notice 1.6kB dist/triggers/jira.d.ts
npm notice 324B dist/triggers/jira.d.ts.map
npm notice 1.4kB dist/triggers/jira.js
npm notice 1.3kB dist/triggers/jira.js.map
npm notice 4.8kB dist/triggers/linear.d.ts
npm notice 563B dist/triggers/linear.d.ts.map
npm notice 4.1kB dist/triggers/linear.js
npm notice 3.2kB dist/triggers/linear.js.map
npm notice 2.1kB dist/triggers/mailgun.d.ts
npm notice 367B dist/triggers/mailgun.d.ts.map
npm notice 1.8kB dist/triggers/mailgun.js
npm notice 1.6kB dist/triggers/mailgun.js.map
npm notice 1.7kB dist/triggers/mixpanel.d.ts
npm notice 332B dist/triggers/mixpanel.d.ts.map
npm notice 1.4kB dist/triggers/mixpanel.js
npm notice 1.3kB dist/triggers/mixpanel.js.map
npm notice 811B dist/triggers/neon.d.ts
npm notice 249B dist/triggers/neon.d.ts.map
npm notice 755B dist/triggers/neon.js
npm notice 693B dist/triggers/neon.js.map
npm notice 1.8kB dist/triggers/notion.d.ts
npm notice 342B dist/triggers/notion.d.ts.map
npm notice 1.6kB dist/triggers/notion.js
npm notice 1.4kB dist/triggers/notion.js.map
npm notice 515B dist/triggers/onedrive.d.ts
npm notice 233B dist/triggers/onedrive.d.ts.map
npm notice 507B dist/triggers/onedrive.js
npm notice 505B dist/triggers/onedrive.js.map
npm notice 2.0kB dist/triggers/pipedrive.d.ts
npm notice 360B dist/triggers/pipedrive.d.ts.map
npm notice 1.7kB dist/triggers/pipedrive.js
npm notice 1.5kB dist/triggers/pipedrive.js.map
npm notice 515B dist/triggers/postgres.d.ts
npm notice 233B dist/triggers/postgres.d.ts.map
npm notice 507B dist/triggers/postgres.js
npm notice 505B dist/triggers/postgres.js.map
npm notice 427B dist/triggers/posthog.d.ts
npm notice 220B dist/triggers/posthog.d.ts.map
npm notice 443B dist/triggers/posthog.js
npm notice 423B dist/triggers/posthog.js.map
npm notice 7.1kB dist/triggers/ramp.d.ts
npm notice 727B dist/triggers/ramp.d.ts.map
npm notice 6.0kB dist/triggers/ramp.js
npm notice 4.5kB dist/triggers/ramp.js.map
npm notice 521B dist/triggers/recall.d.ts
npm notice 229B dist/triggers/recall.d.ts.map
npm notice 513B dist/triggers/recall.js
npm notice 507B dist/triggers/recall.js.map
npm notice 500B dist/triggers/redis.d.ts
npm notice 227B dist/triggers/redis.d.ts.map
npm notice 492B dist/triggers/redis.js
npm notice 499B dist/triggers/redis.js.map
npm notice 485B dist/triggers/s3.d.ts
npm notice 221B dist/triggers/s3.d.ts.map
npm notice 477B dist/triggers/s3.js
npm notice 493B dist/triggers/s3.js.map
npm notice 3.1kB dist/triggers/salesforce.d.ts
npm notice 447B dist/triggers/salesforce.d.ts.map
npm notice 2.6kB dist/triggers/salesforce.js
npm notice 2.2kB dist/triggers/salesforce.js.map
npm notice 1.6kB dist/triggers/segment.d.ts
npm notice 331B dist/triggers/segment.d.ts.map
npm notice 1.4kB dist/triggers/segment.js
npm notice 1.3kB dist/triggers/segment.js.map
npm notice 2.4kB dist/triggers/sendgrid.d.ts
npm notice 389B dist/triggers/sendgrid.d.ts.map
npm notice 2.0kB dist/triggers/sendgrid.js
npm notice 1.8kB dist/triggers/sendgrid.js.map
npm notice 525B dist/triggers/sharepoint.d.ts
npm notice 237B dist/triggers/sharepoint.d.ts.map
npm notice 517B dist/triggers/sharepoint.js
npm notice 509B dist/triggers/sharepoint.js.map
npm notice 3.3kB dist/triggers/shopify.d.ts
npm notice 467B dist/triggers/shopify.d.ts.map
npm notice 2.7kB dist/triggers/shopify.js
npm notice 2.4kB dist/triggers/shopify.js.map
npm notice 887B dist/triggers/shortcut.d.ts
npm notice 266B dist/triggers/shortcut.d.ts.map
npm notice 807B dist/triggers/shortcut.js
npm notice 769B dist/triggers/shortcut.js.map
npm notice 2.8kB dist/triggers/slack.d.ts
npm notice 429B dist/triggers/slack.d.ts.map
npm notice 2.5kB dist/triggers/slack.js
npm notice 2.2kB dist/triggers/slack.js.map
npm notice 3.1kB dist/triggers/stripe.d.ts
npm notice 431B dist/triggers/stripe.d.ts.map
npm notice 2.6kB dist/triggers/stripe.js
npm notice 2.2kB dist/triggers/stripe.js.map
npm notice 2.7kB dist/triggers/teams.d.ts
npm notice 415B dist/triggers/teams.d.ts.map
npm notice 2.3kB dist/triggers/teams.js
npm notice 2.0kB dist/triggers/teams.js.map
npm notice 3.4kB dist/triggers/telegram.d.ts
npm notice 483B dist/triggers/telegram.d.ts.map
npm notice 2.9kB dist/triggers/telegram.js
npm notice 2.5kB dist/triggers/telegram.js.map
npm notice 1.3kB dist/triggers/zendesk.d.ts
npm notice 298B dist/triggers/zendesk.d.ts.map
npm notice 1.2kB dist/triggers/zendesk.js
npm notice 1.0kB dist/triggers/zendesk.js.map
npm notice 1.8kB package.json
npm notice 2.0kB src/cloud.ts
npm notice 893B src/completion.ts
npm notice 3.2kB src/context.ts
npm notice 3.0kB src/effect-transport.ts
npm notice 12.2kB src/flow.ts
npm notice 2.0kB src/helper-clients.ts
npm notice 437B src/helpers/airtable.ts
npm notice 487B src/helpers/asana.ts
npm notice 516B src/helpers/azure-blob.ts
npm notice 473B src/helpers/box.ts
npm notice 508B src/helpers/calendly.ts
npm notice 501B src/helpers/clickup.ts
npm notice 1.9kB src/helpers/clients.ts
npm notice 522B src/helpers/cloudflare.ts
npm notice 522B src/helpers/confluence.ts
npm notice 501B src/helpers/daytona.ts
npm notice 442B src/helpers/docker-hub.ts
npm notice 501B src/helpers/dropbox.ts
npm notice 429B src/helpers/fathom.ts
npm notice 417B src/helpers/gcp.ts
npm notice 473B src/helpers/gcs.ts
npm notice 490B src/helpers/github.ts
npm notice 494B src/helpers/gitlab.ts
npm notice 487B src/helpers/gmail.ts
npm notice 551B src/helpers/google-calendar.ts
npm notice 530B src/helpers/google-drive.ts
npm notice 501B src/helpers/granola.ts
npm notice 501B src/helpers/hubspot.ts
npm notice 9.9kB src/helpers/index.ts
npm notice 508B src/helpers/intercom.ts
npm notice 480B src/helpers/jira.ts
npm notice 494B src/helpers/linear.ts
npm notice 501B src/helpers/mailgun.ts
npm notice 508B src/helpers/mixpanel.ts
npm notice 421B src/helpers/neon.ts
npm notice 490B src/helpers/notion.ts
npm notice 508B src/helpers/onedrive.ts
npm notice 515B src/helpers/pipedrive.ts
npm notice 508B src/helpers/postgres.ts
npm notice 433B src/helpers/posthog.ts
npm notice 6.6kB src/helpers/providers.ts
npm notice 647B src/helpers/ramp.ts
npm notice 2.7kB src/helpers/README.md
npm notice 494B src/helpers/recall.ts
npm notice 494B src/helpers/reddit.ts
npm notice 487B src/helpers/redis.ts
npm notice 466B src/helpers/s3.ts
npm notice 522B src/helpers/salesforce.ts
npm notice 433B src/helpers/segment.ts
npm notice 508B src/helpers/sendgrid.ts
npm notice 522B src/helpers/sharepoint.ts
npm notice 433B src/helpers/shopify.ts
npm notice 508B src/helpers/shortcut.ts
npm notice 905B src/helpers/slack.ts
npm notice 490B src/helpers/stripe.ts
npm notice 487B src/helpers/teams.ts
npm notice 508B src/helpers/telegram.ts
npm notice 458B src/helpers/webhook-server.ts
npm notice 409B src/helpers/x.ts
npm notice 501B src/helpers/zendesk.ts
npm notice 1.6kB src/index.ts
npm notice 812B src/memory.ts
npm notice 277B src/plugin-contract.ts
npm notice 1.2kB src/provider-trigger.ts
npm notice 475B src/runtime.ts
npm notice 13.5kB src/schedule.ts
npm notice 1.8kB src/slack.ts
npm notice 2.6kB src/step.ts
npm notice 2.8kB src/triggers.ts
npm notice 1.2kB src/triggers/airtable.ts
npm notice 2.1kB src/triggers/asana.ts
npm notice 558B src/triggers/azure-blob.ts
npm notice 530B src/triggers/box.ts
npm notice 1.7kB src/triggers/calendly.ts
npm notice 1.5kB src/triggers/clickup.ts
npm notice 1.4kB src/triggers/cloudflare.ts
npm notice 900B src/triggers/confluence.ts
npm notice 1.1kB src/triggers/daytona.ts
npm notice 318B src/triggers/docker-hub.ts
npm notice 328B src/triggers/dropbox.ts
npm notice 352B src/triggers/fathom.ts
npm notice 1.4kB src/triggers/gcp.ts
npm notice 530B src/triggers/gcs.ts
npm notice 3.6kB src/triggers/github.ts
npm notice 6.1kB src/triggers/gitlab.ts
npm notice 538B src/triggers/gmail.ts
npm notice 600B src/triggers/google-calendar.ts
npm notice 566B src/triggers/google-drive.ts
npm notice 671B src/triggers/granola.ts
npm notice 2.6kB src/triggers/hubspot.ts
npm notice 15.0kB src/triggers/index.ts
npm notice 2.4kB src/triggers/intercom.ts
npm notice 1.5kB src/triggers/jira.ts
npm notice 4.4kB src/triggers/linear.ts
npm notice 1.9kB src/triggers/mailgun.ts
npm notice 1.6kB src/triggers/mixpanel.ts
npm notice 818B src/triggers/neon.ts
npm notice 1.7kB src/triggers/notion.ts
npm notice 550B src/triggers/onedrive.ts
npm notice 1.8kB src/triggers/pipedrive.ts
npm notice 550B src/triggers/postgres.ts
npm notice 479B src/triggers/posthog.ts
npm notice 2.7kB src/triggers/PROVIDERS.md
npm notice 6.4kB src/triggers/ramp.ts
npm notice 9.2kB src/triggers/README.md
npm notice 558B src/triggers/recall.ts
npm notice 538B src/triggers/redis.ts
npm notice 526B src/triggers/s3.ts
npm notice 2.8kB src/triggers/salesforce.ts
npm notice 1.5kB src/triggers/segment.ts
npm notice 2.2kB src/triggers/sendgrid.ts
npm notice 558B src/triggers/sharepoint.ts
npm notice 3.0kB src/triggers/shopify.ts
npm notice 874B src/triggers/shortcut.ts
npm notice 2.6kB src/triggers/slack.ts
npm notice 2.8kB src/triggers/stripe.ts
npm notice 2.5kB src/triggers/teams.ts
npm notice 3.1kB src/triggers/telegram.ts
npm notice 1.3kB src/triggers/zendesk.ts
npm notice Tarball Details
npm notice name: @relayflows/surface
npm notice version: 2.0.22
npm notice filename: relayflows-surface-2.0.22.tgz
npm notice package size: 111.5 kB
npm notice unpacked size: 703.6 kB
npm notice shasum: 5316c732461518356203f8e97f87f6a804f006bd
npm notice integrity: sha512-6xYTvDVDGbBCI[...]4t38wwfMJ93/g==
npm notice total files: 585
npm notice
relayflows-surface-2.0.22.tgz

Captured full SDK test command

npm test --prefix packages/sdk

Exit code: 1. Full captured stdout/stderr:


> @relayflows/sdk@2.0.22 test
> sh scripts/test.sh


> @relayflows/sdk@2.0.22 test:prep
> ( cd ../../kernel && sh ../ops/cargo.sh build ) && ( [ ! -d ../../testdata/preflight ] || find ../../testdata/preflight -name '*-cli' -type f -exec chmod +x {} + )

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15s

> @relayflows/sdk@2.0.22 typecheck
> tsc --noEmit && tsc -p tsconfig.type-tests.json


> @relayflows/sdk@2.0.22 build
> tsc && node scripts/make-cli-executable.mjs


> @relayflows/sdk@2.0.22 typecheck:tests
> tsc -p tsconfig.tests.json


 RUN  v2.1.9 /home/daytona/.relayflow-v2-supervisor/durable/repository/packages/sdk

stdout | tests/live-kernel.test.ts
LIVE_KERNEL relayflowd=/home/daytona/.relayflows-toolchain/target/2962130851/debug/relayflowd
LIVE_KERNEL flows=/home/daytona/.relayflow-v2-supervisor/durable/repository/packages/sdk/dist/cli.js

 ✓ tests/cloud-read.test.ts (39 tests) 44ms
 ✓ tests/preflight.test.ts (57 tests) 71ms
 ✓ tests/cli.test.ts (65 tests) 1145ms
   ✓ flows check CLI > binds a checked relative wrapper to the flow directory for worker execution 311ms
 ✓ tests/observer-link.test.ts (39 tests) 126ms
 ✓ tests/cloud-sync.test.ts (40 tests) 697ms
 ✓ tests/agent-transcript.test.ts (29 tests) 254ms
 ✓ tests/cloud-run.test.ts (58 tests) 531ms
(node:53357) ExperimentalWarning: SQLite is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
 ✓ tests/cli-status.test.ts (26 tests) 834ms
   ✓ flows status > resolves the run with no arguments from inside a worker-spawned agent 633ms
 ✓ tests/relay-cli-surface.test.ts (66 tests) 29ms
 ✓ tests/authored-flow.test.ts (25 tests) 744ms
 ✓ tests/daemon-lifecycle.test.ts (42 tests) 35ms
 ✓ tests/run-state.test.ts (21 tests) 11ms
 ✓ tests/cloud-deploy.test.ts (40 tests) 875ms
 ✓ tests/cloud-connect.test.ts (24 tests) 2932ms
   ✓ hosted verbs connect before they submit > flows run --cloud submits once the prompt connected the integration 2107ms
 ✓ tests/step-failure-diagnostic.test.ts (21 tests) 39ms
 ❯ tests/mcp.test.ts (30 tests | 4 skipped) 9203ms
   ✓ MCP preflight and transports > flows check refuses an undeclared server with exit 2 and no daemon 556ms
   ✓ MCP preflight and transports > flows check reports a refusing server and leaves no PID 597ms
   ✓ MCP preflight and transports > kills a SIGTERM-resistant silent child after a parent-owned handshake deadline 1313ms
   ✓ MCP preflight and transports > reaps a SIGTERM-resistant descendant with inherit stdio before cleanup finishes 1109ms
   ✓ MCP preflight and transports > reaps a SIGTERM-resistant descendant with ignore stdio before cleanup finishes 2063ms
   ✓ MCP preflight and transports > reports malformed connection configuration as config_invalid 568ms
 ❯ tests/authored-node-runtime.test.ts (14 tests | 14 skipped) 11ms
 ✓ tests/close-pr-flow.test.ts (28 tests) 299ms
 ✓ tests/journal-client.test.ts (15 tests) 78ms
 ✓ tests/validate.test.ts (68 tests) 20ms
 ✓ tests/verb-field-lint.test.ts (96 tests) 282ms
 ✓ tests/worker-cli.test.ts (18 tests) 22728ms
   ✓ custom wrapper execution identity > bounds wrapper execution after acknowledgement 317ms
   ✓ custom wrapper execution bounds are reader-owned > resolves when a conforming wrapper leaks a stdio pipe to a background helper 1779ms
   ✓ custom wrapper execution bounds are reader-owned > resolves when the leaked helper inherits stderr only 1796ms
   ✓ custom wrapper execution bounds are reader-owned > resolves when a wrapper leaks a stdio pipe and exits before identifying 3474ms
   ✓ custom wrapper execution bounds are reader-owned > journals a completionReason at the default bound when a wrapper leaks a stdio pipe 11493ms
   ✓ custom wrapper execution bounds are reader-owned > accepts the same over-8KiB payload whether or not it coalesces with the execute token 840ms
 ✓ tests/authored-root.test.ts (12 tests) 147ms
 ✓ tests/tick-source.test.ts (33 tests) 24ms
 ✓ tests/agent-relay-transport.test.ts (16 tests) 2218ms
   ✓ Relay completion at the journal boundary > does not complete at readiness and journals exact output, receipt, and priced accounting 1012ms
   ✓ Relay completion at the journal boundary > aborts polling on rejected renewal and never writes a stale completion 1003ms
 ✓ tests/authored-flow-lifecycle-executor.test.ts (27 tests) 589ms
 ✓ tests/pr-review-post.test.ts (21 tests) 2007ms
 ✓ tests/authored-flow-slack.test.ts (7 tests) 1576ms
   ✓ authored Slack helper effects > replays after SIGKILL before confirm with the same token and one successful completion 516ms
   ✓ authored Slack helper effects > replays after SIGKILL before complete with the same token and one successful completion 513ms
 ✓ tests/flow-executor-chain.test.ts (14 tests) 9180ms
   ✓ flow executor LLM and output-binding chain > runs f.llm -> f.agent -> f.run with schema-verified journal output and the exact allowed model 686ms
   ✓ flow executor LLM and output-binding chain > runs a dollar-budgeted authored Claude agent with the same default used by preflight 402ms
   ✓ flow executor LLM and output-binding chain > runs the exact authored flagship f.llm -> f.agent -> f.run path through the durable CLI root 1464ms
   ✓ flow executor LLM and output-binding chain > resumes an interrupted durable authored root without replaying completed flagship effects 3218ms
   ✓ flow executor LLM and output-binding chain > passes a declarative verified value through an agent into a deterministic artifact 553ms
   ✓ flow executor LLM and output-binding chain > journals a missing optional field as a failure before the consuming command executes 316ms
   ✓ flow executor LLM and output-binding chain > flows run consumes YAML bindings and resume reuses the original journal output 1018ms
(node:55493) ExperimentalWarning: SQLite is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
 ✓ tests/tick-runner.test.ts (22 tests) 2283ms
   ✓ CLI argument parsing refuses coercion rather than accepting it > refuses --interval-ms fractional as an invocation error 372ms
   ✓ CLI argument parsing refuses coercion rather than accepting it > refuses --interval-ms exponent notation as an invocation error 375ms
   ✓ CLI argument parsing refuses coercion rather than accepting it > refuses --interval-ms hex as an invocation error 374ms
   ✓ CLI argument parsing refuses coercion rather than accepting it > refuses --interval-ms trailing text as an invocation error 374ms
   ✓ CLI argument parsing refuses coercion rather than accepting it > refuses --interval-ms empty as an invocation error 373ms
   ✓ CLI argument parsing refuses coercion rather than accepting it > accepts an exact integer and proceeds past parsing 385ms
 ✓ tests/cli-replay.test.ts (37 tests) 1116ms
   ✓ flows replay > --json is byte-identical across two CLI invocations (diff) 802ms
 ✓ tests/stop-process-group.test.ts (6 tests) 6575ms
   ✓ every stop reaches the process group, not just the direct child > exits the run after an execution-timeout stop 983ms
   ✓ every stop reaches the process group, not just the direct child > exits the run after a protocol terminate stop 576ms
   ✓ every stop reaches the process group, not just the direct child > kills a SIGTERM-deaf grandchild after a protocol terminate stop 1693ms
   ✓ every stop reaches the process group, not just the direct child > kills a SIGTERM-deaf grandchild after an execution-timeout stop 1988ms
   ✓ every stop reaches the process group, not just the direct child > holds the loop open long enough for the escalation to run 1080ms
 ✓ tests/gate-contract.test.ts (20 tests) 112ms
 ✓ tests/authored-human.test.ts (13 tests) 100ms
 ✓ tests/bundle.test.ts (23 tests) 9027ms
   ✓ immutable bundles > returns exit 2 naming a byte-flipped payload and refuses to reuse corruption 465ms
   ✓ immutable bundles > verifies with --verify in any position and answers --json with one object 1069ms
   ✓ immutable bundles > refuses --out with --verify rather than ignoring the destination 428ms
   ✓ immutable bundles > builds and verifies the canonical YAML fixture through the compiled CLI 1166ms
   ✓ immutable bundles > emits the ephemeral warning on CLI stderr and uses the default output directory 760ms
   ✓ immutable bundles > refuses build-provable CLI resolution errors without environment probes 370ms
   ✓ immutable bundles > builds a standalone TS fixture twice with identical executable hashes 2342ms
   ✓ immutable bundles > refuses to label installed dependency drift with lockfile pins 384ms
   ✓ immutable bundles > refuses invalid CLI arguments %j 362ms
   ✓ immutable bundles > refuses invalid CLI arguments "--out" 413ms
   ✓ immutable bundles > refuses invalid CLI arguments "--verify" 401ms
   ✓ immutable bundles > refuses invalid CLI arguments "--verify" 375ms
   ✓ immutable bundles > refuses invalid CLI arguments "--out" 378ms
 ✓ tests/direct-input.test.ts (6 tests) 5502ms
   ✓ direct .flow.ts input through the built CLI and live runtime > returns exit 3 for an authored human handoff and persists its outcome 614ms
   ✓ direct .flow.ts input through the built CLI and live runtime > returns exit 1 for an authored step_failed verdict and persists its outcome 595ms
   ✓ direct .flow.ts input through the built CLI and live runtime > executes inline and file JSON input through relayflowd 1844ms
   ✓ direct .flow.ts input through the built CLI and live runtime > refuses missing and malformed input before contacting relayflowd 1503ms
   ✓ direct .flow.ts input through the built CLI and live runtime > does not run the authored body before daemon availability 565ms
   ✓ direct .flow.ts input through the built CLI and live runtime > refuses oversized file input before contacting relayflowd 379ms
stdout | tests/live-kernel.test.ts > surface resume after a real daemon kill > resumes a three-step run with each successful completion exactly once
LIVE_KERNEL kill -9 pid=56815 run=01M2ZZ0G48K1MTKTZP8BYQVGM6 while step=two state=Running

 ✓ tests/cloud-schedule.test.ts (17 tests) 4318ms
   ✓ schedule lowering > marks a non-grid cron as Cloud-only rather than approximating it, with a silence budget from its own cadence 1855ms
   ✓ flows check prints declared schedules > shows the lowering for a fixed interval and the Cloud-only note for a real cron 1940ms
 ✓ tests/cli-hn-monitor.test.ts (16 tests) 93ms
 ✓ tests/authored-node-result.test.ts (38 tests) 12ms
 ❯ tests/live-kernel.test.ts (31 tests | 9 failed) 51973ms
   ✓ built flows CLI against live relayflowd > twenty-six-step reuses 25 durable completions after editing the failed final step 2041ms
   ✓ built flows CLI against live relayflowd > runs rung (a), parks rung (b), and keeps JSON report-shaped 2471ms
   ✓ built flows CLI against live relayflowd > allows a deterministic run to exceed the bounded request timeout 32442ms
   ✓ built flows CLI against live relayflowd > follows a live worker dispatch through flows run 865ms
   ✓ built flows CLI against live relayflowd > runs an agent CLI end to end through the SDK worker 509ms
   ✓ built flows CLI against live relayflowd > f.agent lowers to a real agent step and dispatches through a live worker 656ms
   ✓ built flows CLI against live relayflowd > can always get a parked run to a late-attaching worker 5587ms
   ✓ built flows CLI against live relayflowd > reports a real manual-recovery NeedsHuman state as parked 477ms
   × built flows CLI against live relayflowd > runs hn-monitor analyze-story end-to-end via a stub agent CLI (gate 2 clause 2 demo) 422ms
     → expected { …(12) } to match object { output: { …(3) }, …(1) }
(22 matching properties omitted from actual)
   × built flows CLI against live relayflowd > hn-monitor analyze-story FAILS verification when the CLI omits required schema fields 400ms
     → expected { …(12) } to match object { …(3) }
(21 matching properties omitted from actual)
   × built flows CLI against live relayflowd > agent step preserves the CliResult wrapper as output when the CLI emits non-JSON text 354ms
     → expected null not to be null
   × built flows CLI against live relayflowd > AgentWorker exposes wake_context to the CLI via RELAYFLOW_WAKE_CONTEXT env var (real analyzer prerequisite) 377ms
     → Cannot read properties of null (reading 'story_title')
   × built flows CLI against live relayflowd > AgentWorker leaves RELAYFLOW_WAKE_CONTEXT UNSET when the run has no wake_context (undefined-vs-null pin) 325ms
     → Cannot read properties of null (reading 'env_present')
   ✓ built flows CLI against live relayflowd > AgentWorker passes a declared model to an identified wrapper as RELAYFLOW_MODEL 398ms
   ✓ built flows CLI against live relayflowd > AgentWorker refuses a nonconforming journal-submitted wrapper before exposing RELAYFLOW_MODEL 378ms
   ✓ built flows CLI against live relayflowd > AgentWorker executes the raw claude adapter with its real model flag 319ms
   ✓ built flows CLI against live relayflowd > AgentWorker executes the raw codex adapter with its real model flag 308ms
   × built flows CLI against live relayflowd > AgentWorker leaves RELAYFLOW_MODEL UNSET when the step declares no model 338ms
     → Cannot read properties of null (reading 'story_title')
   × built flows CLI against live relayflowd > hn-monitor analyze-story reaches done through the real Claude analyzer CLI 27ms
     → LIVE_ANALYZER_UNAVAILABLE: "/home/daytona/.relayflow-v2-supervisor/durable/repository/testdata/preflight/analyze-story-claude-cli" does not identify as relayflows-agent-cli-v1 — failing because gate-2 acceptance requires the real analyzer to execute. Set RELAYFLOWS_ALLOW_ANALYZER_SKIP=1 only if this run is not gate evidence.
   ✓ built flows CLI against live relayflowd > preflights before journaling and names an unreachable socket 803ms
   × built flows CLI against live relayflowd > starts exactly one daemon when two runs race for one empty data dir 493ms
     → WARNING [unprovable_effects] Step "greet" command "echo" resolves, but its effects cannot be proven before execution.
WARNING [unprovable_effects] Step "shout" command "echo" resolves, but its effects cannot be proven before execution.
WARNING [editor_schema_missing] For editor validation, add this first line: # yaml-language-server: $schema=https://schema.relayflows.dev/v0.1/flows.schema.json
REFUSED [relayflowd_not_found] No relayflowd binary could be found. Install the runtime package for this host (@relayflows/runtime-linux-x64), or set RELAYFLOWD_BIN to a relayflowd executable. Tried: /home/daytona/.relayflow-v2-supervisor/durable/repository/packages/sdk/dist/relayflowd.
: expected 2 to be +0 // Object.is equality
   ✓ surface resume after a real daemon kill > resumes a three-step run with each successful completion exactly once 868ms
   × a relayflow can be scheduled: tick source against live relayflowd > a tick spawns a real run whose step reports the SCHEDULED instant 386ms
     → expected null to deeply equal { schedule_id: 'heartbeat-1m', …(3) }
 ✓ tests/daemon-lifecycle-live.test.ts (9 tests) 6321ms
   ✓ flows run against a data dir with no daemon (§6 test 7) > cold start spawns exactly one daemon, the run succeeds, and the daemon outlives the CLI 451ms
   ✓ flows run against a data dir with no daemon (§6 test 7) > polls, bounded, for a daemon that holds the lock before it binds 1371ms
   ✓ flows run against a data dir with no daemon (§6 test 7) > attaches to a serving daemon that has not published a connection file 450ms
   ✓ flows run against a data dir with no daemon (§6 test 7) > a second run attaches to the daemon the first one started, spawning nothing 826ms
   ✓ flows run against a data dir with no daemon (§6 test 7) > detects a stale connection file left by a hard kill and starts a fresh daemon 908ms
   ✓ concurrent invocations against one empty data dir (§6 test 15) > ends with exactly one daemon owning the socket, and both runs succeed 1051ms
   ✓ refusals from a spawn that cannot produce a daemon > names relayflowd_not_found rather than falling through to PATH 389ms
   ✓ refusals from a spawn that cannot produce a daemon > names daemon_start_failed and quotes the daemon log when startup dies 436ms
   ✓ refusals from a spawn that cannot produce a daemon > refuses a daemon speaking another protocol version instead of binding over it 438ms
(node:57429) Warning: Transcript tail for run-9/analyze attempt 1 (stdout) could not be written; the step continues without it: EACCES: permission denied, mkdir '/tmp/transcript-tail-TaFOH5/runs/run-9/steps'
(Use `node --trace-warnings ...` to show where the warning was created)
 ✓ tests/transcript-tail.test.ts (11 tests) 605ms
 ✓ tests/authored-agent-artifacts.test.ts (4 tests) 368ms
 ✓ tests/authored-helpers.test.ts (6 tests) 2877ms
   ✓ runs every available provider through the real kernel and resumes completed effects without a second write 1481ms
   ✓ replays after SIGKILL before confirm with the same token and one successful completion 501ms
   ✓ replays after SIGKILL before complete with the same token and one successful completion 493ms
 ✓ tests/helper-partial-support.test.ts (12 tests) 120ms
 ✓ tests/backlog-picker.test.ts (14 tests) 44ms
 ✓ tests/backlog-picker-flow.test.ts (6 tests) 262ms
 ✓ tests/preflight-permissions-unenforced.test.ts (17 tests) 226ms
 ❯ tests/stuck-run-triage.test.ts (22 tests | 22 failed) 65ms
   × stuck-run-triage input validation > refuses an 8-character run-id prefix: Cloud has no prefix lookup 4ms
     → expected [Function] to throw error matching /not full Cloud run ids: c649fe14/ but got 'expected an @relayflows/surface flow …'
   × stuck-run-triage input validation > refuses the whole batch when any id is invalid, rather than dropping it 1ms
     → expected [Function] to throw error matching /not full Cloud run ids: nope!/ but got 'expected an @relayflows/surface flow …'
   × stuck-run-triage input validation > refuses an empty batch 0ms
     → expected [Function] to throw error matching /needs runIds/ but got 'expected an @relayflows/surface flow …'
   × stuck-run-triage input validation > refuses a batch too large for the edge step lease 0ms
     → expected [Function] to throw error matching /exceeds the 8 that fit/ but got 'expected an @relayflows/surface flow …'
   × stuck-run-triage input validation > accepts eight ids — the incident batch is inside the bound 3ms
     → promise rejected "TypeError: expected an @relayflows/surfac…" instead of resolving
   × stuck-run-triage apiUrl > refuses to send the Cloud bearer token to an unapproved origin 0ms
     → expected [Function] to throw error matching /refusing to send the Cloud bearer to…/\ but got 'expected an @relayflows/surface flow …'
   × stuck-run-triage apiUrl > refuses a non-URL apiUrl 0ms
     → expected [Function] to throw error matching /is not a URL/ but got 'expected an @relayflows/surface flow …'
   × stuck-run-triage apiUrl > allows an approved origin and uses it in the curl 0ms
     → expected an @relayflows/surface flow handle
   × stuck-run-triage apiUrl > defaults to production Cloud 0ms
     → expected an @relayflows/surface flow handle
   × stuck-run-triage apiUrl > never publishes a run record the fetch did not produce 0ms
     → expected an @relayflows/surface flow handle
   × stuck-run-triage edge collection > names the Worker on every wrangler invocation 0ms
     → expected an @relayflows/surface flow handle
   × stuck-run-triage edge collection > accepts caller-supplied Workers and rejects option-shaped ones 0ms
     → expected an @relayflows/surface flow handle
   × stuck-run-triage edge collection > falls back when GNU timeout is absent, as it is on macOS 0ms
     → expected an @relayflows/surface flow handle
   × stuck-run-triage edge collection > runs the tails concurrently so wall time does not scale with the batch 0ms
     → expected an @relayflows/surface flow handle
   × stuck-run-triage edge collection > records wrangler's own exit status rather than head's 0ms
     → expected an @relayflows/surface flow handle
   × stuck-run-triage shell text > parses under both sh and bash 0ms
     → expected an @relayflows/surface flow handle
   × stuck-run-triage shell text > collects tails with no GNU timeout on PATH, as on a stock macOS 49ms
     → expected an @relayflows/surface flow handle
   × stuck-run-triage agents > declares read-only permissions on every agent 0ms
     → expected an @relayflows/surface flow handle
   × stuck-run-triage agents > tells the forensics agents their evidence is untrusted 0ms
     → expected an @relayflows/surface flow handle
   × stuck-run-triage fan-out > refuses a duplicate run id: two tails would share one evidence file 1ms
     → expected [Function] to throw error matching /duplicate runIds: c649fe14-0c2e-4e51-…/ but got 'expected an @relayflows/surface flow …'
   × stuck-run-triage fan-out > refuses a duplicate Worker name for the same reason 0ms
     → expected [Function] to throw error matching /duplicate workers: w-one/ but got 'expected an @relayflows/surface flow …'
   × stuck-run-triage fan-out > bounds ids x workers, not just ids 0ms
     → expected [Function] to throw error matching /24 concurrent tails, over the 16/ but got 'expected an @relayflows/surface flow …'
 ✓ tests/worker-transcript.test.ts (5 tests) 190ms
 ✓ tests/flow-requirements.test.ts (13 tests) 450ms
 ✓ tests/webhook.test.ts (9 tests) 432ms
   ✓ webhook ingress > checks TS declarations against flows.json without invoking handlers 354ms
 ✓ tests/authored-run-failure-evidence.test.ts (8 tests) 860ms
   ✓ the child index after the process that wrote it is gone > still names every child, with its own run id, after a daemon restart 483ms
 ✓ tests/agent-transcript-live.test.ts (4 tests) 41295ms
   ✓ the transcript digest through the built CLI, a real daemon and the local agent > preserves structured agent failure details and its completed root index 13139ms
   ✓ the transcript digest through the built CLI, a real daemon and the local agent > preserves structured llm failure details and its completed root index 14123ms
   ✓ the transcript digest through the built CLI, a real daemon and the local agent > journals the digest in trajectory_tail on a successful agent step and writes the file it points at 760ms
   ✓ the transcript digest through the built CLI, a real daemon and the local agent > on a failed agent step, names the failure and the transcript in the terminal diagnostic, redacted 13273ms
 ✓ tests/agent-artifacts-live.test.ts (5 tests) 42171ms
   ✓ agent artifacts and gates through the built CLI, a real daemon and the local agent > journals the files the agent wrote, and both artifact gates pass on that journal 1008ms
   ✓ agent artifacts and gates through the built CLI, a real daemon and the local agent > fails the run when the artifact_exists gate names a file the agent did not write 12964ms
   ✓ agent artifacts and gates through the built CLI, a real daemon and the local agent > fails the run with the author reason when a predicate gate returns false, journaling the verdict 13455ms
   ✓ review follow-ups > applies a predicate gate on a helper step too, and journals its verdict 14114ms
   ✓ review follow-ups > records predicate verdicts on the root run so a resume reuses them instead of re-running the closure 630ms
 ✓ tests/human-live.test.ts (3 tests) 6086ms
   ✓ f.human against a real daemon > parks with the question, refuses wrong answers, records one, and resumes to success 3603ms
   ✓ f.human against a real daemon > a "no" is a value the body branches on: declined, exit 0, no effect 1515ms
   ✓ f.human against a real daemon > refuses to answer a run the daemon does not know 967ms
 ✓ tests/authored-step-failed.test.ts (10 tests) 34ms
 ✓ tests/authored-flow-operation.test.ts (23 tests) 349ms
 ✓ tests/cli-watch.test.ts (10 tests) 15221ms
   ✓ flows check --watch > rechecks syntax errors, clears once, and returns the last refusal on Ctrl-C 1276ms
   ✓ flows check --watch > streams JSON lines without ANSI, recovers after atomic saves, and exits zero after repair 1773ms
   ✓ flows check --watch > coalesces 20 concurrent saves into at most two rechecks 1771ms
   ✓ flows check --watch > watches transitive relative use imports, cycles, and nearest config changes 2303ms
   ✓ flows check --watch > refreshes the import graph and notices missing imports being created 2265ms
   ✓ flows check --watch > reloads authored TypeScript instead of reusing the first imported definition 1491ms
   ✓ flows check --watch > detects a nearer config appearing and falls back after it is deleted 1794ms
   ✓ flows check --watch > keeps watching after the target is deleted and recreated 1772ms
   ✓ flows check --watch > queues changes during a slow check without overlapping checks 773ms
 ✓ tests/budget-preflight.test.ts (25 tests) 15ms
 ✓ tests/authored-step-index.test.ts (12 tests) 13ms
 ✓ tests/artifact-gates.test.ts (6 tests) 123ms
 ✓ tests/helpers-fanout.test.ts (96 tests) 132ms
 ✓ tests/budget-unmetered-live.test.ts (3 tests) 965ms
   ✓ unmetered budget spend through the live kernel > runs an unpriced step under a dollar budget without tripping it, journaling unknown dollars 465ms
 ✓ tests/provider-trigger-contract.test.ts (7 tests) 513ms
   ✓ provider trigger contract > fails `flows check` before deployment and passes once the event is real 321ms
 ✓ tests/work-package-consumer.test.ts (13 tests) 104ms
 ✓ tests/spec-parity.test.ts (31 tests) 328ms
 ✓ tests/generate-triggers.test.ts (7 tests) 997ms
   ✓ discovers new adapters, preserves exact event names, and prefers adapter-local mappings 325ms
 ✓ tests/pty-sidechannel.test.ts (11 tests) 4914ms
   ✓ view attach preserves worker completion and marks only drive 723ms
   ✓ passthrough attach preserves worker completion and marks only drive 708ms
   ✓ none attach preserves worker completion and marks only drive 719ms
   ✓ none subscriber lets an unattended CLI read EOF 335ms
   ✓ view subscriber lets an unattended CLI read EOF 338ms
   ✓ passthrough subscriber lets an unattended CLI read EOF 337ms
   ✓ incomplete subscriber lets an unattended CLI read EOF 334ms
   ✓ rejects drive after EOF without marking human intervention 629ms
   ✓ delivers all drive bytes in order across child stdin backpressure 521ms
 ✓ tests/webhook-hardening.test.ts (11 tests) 64ms
 ✓ tests/human-to.test.ts (8 tests) 9ms
 ✓ tests/plugin-loader.test.ts (9 tests) 165ms
 ❯ tests/webhook-live.test.ts (6 tests | 6 failed) 62478ms
   × executes and deduplicates 'app_mention' only for its provider and matching payload 10442ms
     → webhook integration timed out: spawn /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/debug/relayflowd ENOENT
   × executes and deduplicates 'reaction_added' only for its provider and matching payload 10408ms
     → webhook integration timed out: spawn /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/debug/relayflowd ENOENT
   × executes and deduplicates 'pull_request' only for its provider and matching payload 10412ms
     → webhook integration timed out: spawn /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/debug/relayflowd ENOENT
   × flows serve-webhook writes JSON before the daemon starts, then journals and archives exactly once 10426ms
     → webhook integration timed out: spawn /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/debug/relayflowd ENOENT
   × replays a dropped file after SIGKILL before spawn 10396ms
     → webhook integration timed out: spawn /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/debug/relayflowd ENOENT
   × resumes the same journal after SIGKILL after spawn and before acknowledgement 10394ms
     → webhook integration timed out: spawn /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/debug/relayflowd ENOENT
 ✓ tests/worker-lease.test.ts (7 tests) 10ms
 ✓ tests/yaml-helpers.test.ts (33 tests) 66ms
 ✓ tests/authored-agent-permissions.test.ts (26 tests) 707ms
 ✓ tests/worker-cli-result-exit.test.ts (5 tests) 32862ms
   ✓ a Claude agent step completes on its result, not only on process exit > settles a hung, successful run within the grace and stops its whole tree 31603ms
   ✓ a Claude agent step completes on its result, not only on process exit > maps an error result on a hung run to a failed exit 31603ms
   ✓ a Claude agent step completes on its result, not only on process exit > leaves a hang before any result to the existing stops 32009ms
   ✓ an agent tree does not outlive the process that spawned it > kills the agent group when the run process is terminated by SIGTERM 773ms
 ✓ tests/redact.test.ts (35 tests) 7ms
 ✓ tests/communication.test.ts (10 tests) 13ms
 ✓ tests/typed-output.test.ts (14 tests) 188ms
 ✓ tests/budget-attribution.test.ts (5 tests) 7ms
 ✓ tests/json-schema-bound.test.ts (71 tests) 2244ms
   ✓ JSON Schema termination bound > walks a deep schema with an explicit stack rather than recursion 1831ms
 ✓ tests/effect-channel.test.ts (5 tests) 338ms
 ✓ tests/deploy.test.ts (11 tests) 4858ms
   ✓ flows deploy file buckets > publishes the full signed layout byte-for-byte and redeploys as a noop 770ms
   ✓ flows deploy file buckets > answers --json with one object per outcome 740ms
   ✓ flows deploy file buckets > reports a refusal as JSON under --json 370ms
   ✓ flows deploy file buckets > refuses a missing local bundle before creating the bucket 356ms
   ✓ flows deploy file buckets > refuses an unreachable bucket before copying 374ms
   ✓ flows deploy file buckets > refuses an unwritable bucket 376ms
   ✓ flows deploy file buckets > refuses local tampering of spec.canonical.json 359ms
   ✓ flows deploy file buckets > refuses local tampering of identity.json 368ms
   ✓ flows deploy file buckets > refuses asset bundles instead of using daemon-relative files 363ms
   ✓ flows deploy file buckets > never labels a corrupt existing deployment as a noop 751ms
 ✓ tests/mcp-lifecycle.test.ts (4 tests) 12ms
 ✓ tests/model-selection.test.ts (10 tests) 16ms
 ✓ tests/relayflowd-path.test.ts (10 tests) 5ms
 ✓ tests/f-memory.test.ts (7 tests) 765ms
 ✓ tests/authored-plugin-effect.test.ts (6 tests) 54ms
 ✓ tests/yaml-local-agent-live.test.ts (7 tests) 3905ms
   ✓ YAML --local-agent through the built CLI and real daemon > runs with the checked step CLI and model and journals done 587ms
   ✓ YAML --local-agent through the built CLI and real daemon > runs with the checked named CLI and model and journals done 575ms
   ✓ YAML --local-agent through the built CLI and real daemon > runs with the checked flow CLI and model and journals done 563ms
   ✓ YAML --local-agent through the built CLI and real daemon > runs with the checked project CLI and model and journals done 572ms
   ✓ YAML --local-agent through the built CLI and real daemon > still parks without --local-agent 514ms
   ✓ YAML --local-agent through the built CLI and real daemon > reports the agent process failure 580ms
   ✓ YAML --local-agent through the built CLI and real daemon > preserves declared workspace surfaces that the local worker cannot pin 514ms
 ✓ tests/local-dev-ux.test.ts (8 tests) 16ms
 ↓ tests/relay-cli-surface-live.test.ts (3 tests | 3 skipped)
 ✓ tests/authored-declined.test.ts (13 tests) 47ms
 ✓ tests/resume-failure.test.ts (2 tests) 5ms
 ✓ tests/dependency-validation.test.ts (6 tests) 586ms
   ✓ dependency validation > accepts a valid 10,000-step reverse chain through every direct public boundary 330ms
 ✓ tests/input-binding.test.ts (12 tests) 201ms
 ✓ tests/communication-review.test.ts (5 tests) 317ms
 ✓ tests/yaml-helper-effect.test.ts (4 tests) 73ms
 ✓ tests/deterministic-llm.test.ts (5 tests) 49ms
 ✓ tests/scope-preflight.test.ts (6 tests) 7ms
 ✓ tests/bin.test.ts (7 tests) 2326ms
   ✓ built flows binary > refuses through a symlink to the built artifact 368ms
   ✓ built flows binary > refuses through a symlinked directory component 377ms
   ✓ built flows binary > classifies a signal-terminated auth probe as probe_failed 466ms
   ✓ built flows binary > classifies an unavailable PATH resolver as probe_failed 370ms
   ✓ built flows binary > does not describe a present non-executable CLI as missing 367ms
   ✓ built flows binary > runs one auth probe for three steps sharing a flow CLI 376ms
 ✓ tests/build-gate.test.ts (3 tests) 1137ms
   ✓ flows build gates on flows check green (#318) > refuses a flow with an unresolvable named-agent CLI and leaves no artifacts 366ms
   ✓ flows build gates on flows check green (#318) > --json emits one CheckReport object on stdout on refusal, exits 2, no artifacts 372ms
   ✓ flows build gates on flows check green (#318) > builds the bundle on success (regression: gate must not block valid flows) 399ms
 ✓ tests/scope-compiler.test.ts (25 tests) 12ms
 ✓ tests/run-from-digest.test.ts (6 tests) 4173ms
   ✓ flows run digest input > submits the sealed canonical spec through the normal journal path without checkout 416ms
   ✓ flows run digest input > uses a verified cache hit even after the bucket is removed 387ms
   ✓ flows run digest input > resolves deploy.bucket from flows.json and honors explicit override 1131ms
   ✓ flows run digest input > refuses an unconfigured bucket 742ms
   ✓ flows run digest input > refuses tampered spec.canonical.json before creating run data 754ms
   ✓ flows run digest input > refuses tampered identity.json before creating run data 743ms
 ✓ tests/communication-worker.test.ts (15 tests) 1492ms
 ✓ tests/hn-poller.test.ts (6 tests) 6ms
 ✓ tests/plugin-add.test.ts (7 tests) 1135ms
   ✓ typechecks the augmented verb and rejects unknown namespaces 838ms
 ✓ tests/authored-step-failed-exit.test.ts (3 tests) 8ms
 ✓ tests/direct-run-failure.test.ts (8 tests) 12ms
 ✓ tests/dir-watcher-poller.test.ts (6 tests) 4ms
 ✓ tests/model-pricing.test.ts (10 tests) 5ms
 ✓ tests/yaml-helper-live.test.ts (1 test) 904ms
   ✓ runs compiled YAML helpers through the built CLI and kernel effect journal 903ms
 ❯ tests/provider-trigger-executor.test.ts (4 tests | 3 failed) 17ms
   × the kernel executes compiled 'app_mention' subscriptions with provider isolation and durable dedupe 8ms
     → spawnSync /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/debug/relayflowd ENOENT
   × the kernel executes compiled 'reaction_added' subscriptions with provider isolation and durable dedupe 3ms
     → spawnSync /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/debug/relayflowd ENOENT
   × the kernel executes compiled 'pull_request' subscriptions with provider isolation and durable dedupe 3ms
     → spawnSync /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/debug/relayflowd ENOENT
 ✓ tests/transcript-tail-close.test.ts (2 tests) 832ms
   ✓ a stalled transcript-tail close > does not hold the spawn open past its bounded window 413ms
   ✓ a stalled tail close beside a transcript that finished > still journals the transcript pointer 417ms
 ✓ tests/wrapper-artifacts-cwd.test.ts (2 tests) 68ms
 ✓ tests/hello-deterministic.test.ts (5 tests) 17ms
 ✓ tests/transcript-exclusion-timeout.test.ts (1 test) 184ms
 ✓ tests/cli-adapter.test.ts (4 tests) 5ms
 ❯ tests/communication-mixed-resume.test.ts (1 test | 1 failed) 12ms
   × resumes mixed ordinary and linked agents through the real daemon without stealing peer capacity 11ms
     → ENOENT: no such file or directory, open '/tmp/communication-resume-1ljgN0/data/connection.json'
 ✓ tests/work-package-validator.test.ts (7 tests) 5ms
 ✓ tests/authored-use-loader.test.ts (5 tests) 600ms
 ✓ tests/authored-declined-live.test.ts (1 test) 1534ms
   ✓ runs an input guard and resumes its completed declined root without repeated effects 1533ms
 ✓ tests/cli-answer.test.ts (15 tests) 8ms
 ✓ tests/bundle-preflight.test.ts (4 tests) 825ms
   ✓ bundle execution preflight > ignores surrounding cache configuration on a verified cache hit 411ms
   ✓ bundle execution preflight > uses the built alias for a nameless flow even in a digest-only cache directory 389ms
 ✓ tests/agent-relay-hardening.test.ts (12 tests) 12ms
 ✓ tests/classify-outcome.test.ts (2 tests) 2159ms
   ✓ classifyOutcome > gives up and reports when a running run never becomes classifiable 2006ms
 ✓ tests/communication-preflight.test.ts (13 tests) 28ms
 ✓ tests/agent-artifacts.test.ts (6 tests) 11ms
 ↓ tests/real-cli-adapters.test.ts (3 tests | 3 skipped)
 ✓ tests/memoization.test.ts (57 tests) 51ms
 ✓ tests/parse-json-output.test.ts (7 tests) 3ms
 ✓ tests/journal-client-completion.test.ts (4 tests) 100ms
 ✓ tests/worker-cli-abort.test.ts (2 tests) 2394ms
   ✓ stops claude and its process group when lease ownership is lost 1208ms
   ✓ stops wrapper.mjs and its process group when lease ownership is lost 1185ms
 ✓ tests/communication-environment-preflight.test.ts (6 tests) 4ms
 ✓ tests/budget-authored-live.test.ts (2 tests) 192ms
 ✓ tests/slack-writeback.test.ts (1 test) 258ms
 ✓ tests/authored-surface-authority.test.ts (2 tests) 16ms
 ✓ tests/adapters/claude.test.ts (7 tests) 4ms
 ✓ tests/worker-cli-cwd.test.ts (2 tests) 249ms
 ✓ tests/adapters/codex.test.ts (7 tests) 4ms
 ✓ tests/slack-block-kit.test.ts (5 tests) 13ms
 ✓ tests/communication-history.test.ts (1 test) 3ms
 ✓ tests/adapters/registry.test.ts (4 tests) 4ms
 ✓ tests/authored-declined-report.test.ts (6 tests) 7ms
 ✓ tests/communication-refusal.test.ts (1 test) 12ms
 ✓ tests/bundle-transport.test.ts (20 tests) 2344ms
   ✓ digest references > accepts and deploys the build output for hello 399ms
   ✓ digest references > accepts and deploys the build output for Hello 395ms
   ✓ digest references > accepts and deploys the build output for hello.world 384ms
   ✓ digest references > accepts and deploys the build output for hello_world 382ms
   ✓ digest references > accepts and deploys the build output for 123 385ms
   ✓ digest references > accepts and deploys the build output for A_b.c-1 397ms
 ✓ tests/check-command-cwd.test.ts (1 test) 12ms
 ✓ tests/communication-lazy.test.ts (1 test) 4ms
 ✓ tests/cli-progress-wait.test.ts (2 tests) 4ms
 ↓ tests/run-digest-live.test.ts (1 test | 1 skipped)
 ✓ tests/placement.test.ts (54 tests) 16ms
 ✓ tests/step-lease.test.ts (36 tests) 66494ms
   ✓ f.run leases against the live kernel > enforces 10000 ms for 'sleep 5; printf ok' 5081ms
   ✓ f.run leases against the live kernel > enforces 40000 ms for 'sleep 31; printf ok' 31080ms
   ✓ f.run leases against the live kernel > enforces 30000 ms for 'sleep 31; printf ok' 30111ms
 ✓ tests/communication-tools.test.ts (1 test) 71ms
 ✓ tests/authored-admission.test.ts (2 tests) 3ms
 ✓ tests/memory.test.ts (18 tests) 7ms
 ✓ tests/worker-platform.test.ts (1 test) 3ms
 ✓ tests/run-digest.test.ts (4 tests) 1499ms
   ✓ digest run configuration refusals > reports config_invalid before fetching or starting a run for {invalid json 391ms
   ✓ digest run configuration refusals > reports config_invalid before fetching or starting a run for {"deploy":{}} 383ms
   ✓ digest run configuration refusals > reports config_invalid before fetching or starting a run for {"deploy":{"bucket":123}} 365ms
   ✓ digest run configuration refusals > reports config_invalid before fetching or starting a run for {"deploy":{"bucket":""}} 359ms
 ✓ tests/local-agent-live.test.ts (5 tests) 64452ms
   ✓ built CLI local agent against a real daemon > dispatches through the wrapper and keeps --json stdout report-shaped 720ms
   ✓ built CLI local agent against a real daemon > runs beyond the initial 30-second lease without a second invocation 35752ms
   ✓ built CLI local agent against a real daemon > renders actual agent completion in text output 723ms
   ✓ built CLI local agent against a real daemon > returns a failed run when the agent process fails 12312ms
   ✓ built CLI local agent against a real daemon > refuses a workspace it cannot pin before invoking the agent 14945ms

⎯⎯⎯⎯⎯⎯ Failed Suites 2 ⎯⎯⎯⎯⎯⎯⎯

 FAIL  tests/authored-node-runtime.test.ts [ tests/authored-node-runtime.test.ts ]
AssertionError: expected '1.3.6' to be '1.4.0' // Object.is equality

Expected: "1.4.0"
Received: "1.3.6"

 ❯ tests/authored-node-runtime.test.ts:18:77
     16| 
     17| beforeAll(() => {
     18|   expect(spawnSync(bun, ['--version'], { encoding: 'utf8' }).stdout.tr…
       |                                                                             ^
     19|   expect(existsSync(daemon), 'build the current kernel or set RELAYFLO…
     20|   stage = mkdtempSync(join(tmpdir(), 'authored-standalone-build-'));

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/43]⎯

 FAIL  tests/mcp.test.ts > authored MCP effects against the real kernel
Error: journal client: connect failed: connect ENOENT /tmp/relayflowd-e1a635f4c46d.sock
 ❯ Socket.onError src/journal-client.ts:100:16
     98|         socket.removeAllListeners();
     99|         this.failAll(err);
    100|         reject(new Error(`journal client: connect failed: ${err.messag…
       |                ^
    101|       };
    102|       socket.once('error', onError);

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/43]⎯

⎯⎯⎯⎯⎯⎯ Failed Tests 41 ⎯⎯⎯⎯⎯⎯⎯

 FAIL  tests/communication-mixed-resume.test.ts > resumes mixed ordinary and linked agents through the real daemon without stealing peer capacity
Error: ENOENT: no such file or directory, open '/tmp/communication-resume-1ljgN0/data/connection.json'
 ❯ tests/communication-mixed-resume.test.ts:54:35
     52|   } finally {
     53|     clearTimeout(timeout); state.release(); client.close();
     54|     try { process.kill(JSON.parse(readFileSync(join(dataDir, 'connecti…
       |                                   ^
     55|     finally { rmSync(root, { recursive: true, force: true }); }
     56|   }

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/43]⎯

 FAIL  tests/live-kernel.test.ts > built flows CLI against live relayflowd > runs hn-monitor analyze-story end-to-end via a stub agent CLI (gate 2 clause 2 demo)
AssertionError: expected { …(12) } to match object { output: { …(3) }, …(1) }
(22 matching properties omitted from actual)

- Expected
+ Received

  Object {
-   "output": Object {
-     "reasoning": "stub agent runtime — deterministic output for gate-2 clause-2 demo",
-     "relevance_score": 5,
-     "story_title": "stub",
-   },
+   "output": null,
    "verification": Object {
-     "gate": "json_schema",
-     "verdict": "pass",
+     "gate": "execution",
+     "verdict": "fail",
    },
  }

 ❯ tests/live-kernel.test.ts:657:36
    655|         && (entry as { step_id?: string }).step_id === 'analyze-story',
    656|     ) as { payload: { output: unknown; verification: unknown } } | und…
    657|     expect(stepCompleted?.payload).toMatchObject({
       |                                    ^
    658|       output: {
    659|         story_title: 'stub',

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/43]⎯

 FAIL  tests/live-kernel.test.ts > built flows CLI against live relayflowd > hn-monitor analyze-story FAILS verification when the CLI omits required schema fields
AssertionError: expected { …(12) } to match object { …(3) }
(21 matching properties omitted from actual)

- Expected
+ Received

  Object {
-   "completionReason": "retries_exhausted",
+   "completionReason": "worker_error",
    "output": null,
    "verification": Object {
-     "gate": "json_schema",
+     "gate": "execution",
      "verdict": "fail",
    },
  }

 ❯ tests/live-kernel.test.ts:752:36
    750|     // its verification record names the json_schema rejection. The re…
    751|     // parsed value is nulled before the completion is persisted.
    752|     expect(stepCompleted?.payload).toMatchObject({
       |                                    ^
    753|       completionReason: 'retries_exhausted',
    754|       output: null,

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/43]⎯

 FAIL  tests/live-kernel.test.ts > built flows CLI against live relayflowd > agent step preserves the CliResult wrapper as output when the CLI emits non-JSON text
AssertionError: expected null not to be null
 ❯ tests/live-kernel.test.ts:823:24
    821|     // here (parseJsonOutput returned null on non-JSON stdout) and
    822|     // these assertions would all fail.
    823|     expect(output).not.toBeNull();
       |                        ^
    824|     expect(output.exit_code).toBe(0);
    825|     expect(output.stdout_tail).toContain('looked at the story');

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/43]⎯

 FAIL  tests/live-kernel.test.ts > built flows CLI against live relayflowd > AgentWorker exposes wake_context to the CLI via RELAYFLOW_WAKE_CONTEXT env var (real analyzer prerequisite)
TypeError: Cannot read properties of null (reading 'story_title')
 ❯ tests/live-kernel.test.ts:891:42
    889|     ) as { payload: { output: { story_title: string; reasoning: string…
    890|     expect(stepCompleted).toBeDefined();
    891|     expect(stepCompleted!.payload.output.story_title).toBe(`echoed:${s…
       |                                          ^
    892|     expect(stepCompleted!.payload.output.reasoning).toContain(String(s…
    893| 

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[7/43]⎯

 FAIL  tests/live-kernel.test.ts > built flows CLI against live relayflowd > AgentWorker leaves RELAYFLOW_WAKE_CONTEXT UNSET when the run has no wake_context (undefined-vs-null pin)
TypeError: Cannot read properties of null (reading 'env_present')
 ❯ tests/live-kernel.test.ts:958:38
    956|     ) as { payload: { output: { env_present: boolean } } } | undefined;
    957|     expect(completed).toBeDefined();
    958|     expect(completed!.payload.output.env_present).toBe(false);
       |                                      ^
    959| 
    960|     delete process.env.RELAYFLOW_WAKE_CONTEXT;

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[8/43]⎯

 FAIL  tests/live-kernel.test.ts > built flows CLI against live relayflowd > AgentWorker leaves RELAYFLOW_MODEL UNSET when the step declares no model
TypeError: Cannot read properties of null (reading 'story_title')
 ❯ tests/live-kernel.test.ts:1194:38
    1192|     expect(completed).toBeDefined();
    1193|     // UNSET, not EMPTY and not the leaked parent value.
    1194|     expect(completed!.payload.output.story_title).toBe('model:UNSET');
       |                                      ^
    1195| 
    1196|     delete process.env.RELAYFLOW_MODEL;

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[9/43]⎯

 FAIL  tests/live-kernel.test.ts > built flows CLI against live relayflowd > hn-monitor analyze-story reaches done through the real Claude analyzer CLI
Error: LIVE_ANALYZER_UNAVAILABLE: "/home/daytona/.relayflow-v2-supervisor/durable/repository/testdata/preflight/analyze-story-claude-cli" does not identify as relayflows-agent-cli-v1 — failing because gate-2 acceptance requires the real analyzer to execute. Set RELAYFLOWS_ALLOW_ANALYZER_SKIP=1 only if this run is not gate evidence.
 ❯ tests/live-kernel.test.ts:1223:15
    1221|       const notice = `LIVE_ANALYZER_UNAVAILABLE: ${readiness.detail}`;
    1222|       if (process.env['RELAYFLOWS_ALLOW_ANALYZER_SKIP'] !== '1') {
    1223|         throw new Error(
       |               ^
    1224|           `${notice} — failing because gate-2 acceptance requires the …
    1225|           + 'Set RELAYFLOWS_ALLOW_ANALYZER_SKIP=1 only if this run is …

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[10/43]⎯

 FAIL  tests/live-kernel.test.ts > built flows CLI against live relayflowd > starts exactly one daemon when two runs race for one empty data dir
AssertionError: WARNING [unprovable_effects] Step "greet" command "echo" resolves, but its effects cannot be proven before execution.
WARNING [unprovable_effects] Step "shout" command "echo" resolves, but its effects cannot be proven before execution.
WARNING [editor_schema_missing] For editor validation, add this first line: # yaml-language-server: $schema=https://schema.relayflows.dev/v0.1/flows.schema.json
REFUSED [relayflowd_not_found] No relayflowd binary could be found. Install the runtime package for this host (@relayflows/runtime-linux-x64), or set RELAYFLOWD_BIN to a relayflowd executable. Tried: /home/daytona/.relayflow-v2-supervisor/durable/repository/packages/sdk/dist/relayflowd.
: expected 2 to be +0 // Object.is equality

- Expected
+ Received

- 0
+ 2

 ❯ tests/live-kernel.test.ts:1388:40
    1386|     ]);
    1387| 
    1388|     expect(first.status, first.stderr).toBe(0);
       |                                        ^
    1389|     expect(second.status, second.stderr).toBe(0);
    1390|     expect(first.stdout).toContain('completionReason: success');

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[11/43]⎯

 FAIL  tests/live-kernel.test.ts > a relayflow can be scheduled: tick source against live relayflowd > a tick spawns a real run whose step reports the SCHEDULED instant
AssertionError: expected null to deeply equal { schedule_id: 'heartbeat-1m', …(3) }

- Expected: 
Object {
  "lag_ms": 43000,
  "schedule_id": "heartbeat-1m",
  "scheduled_for_ms": 1764000000000,
  "slot": 29400000,
}

+ Received: 
null

 ❯ tests/live-kernel.test.ts:1665:39
    1663|     // The bound: the run reports the grid instant and its own lag, so…
    1664|     // backfilled run can tell it is running for a slot from the past.
    1665|     expect(completed!.payload.output).toEqual({
       |                                       ^
    1666|       schedule_id: 'heartbeat-1m',
    1667|       slot: 29_400_000,

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[12/43]⎯

 FAIL  tests/provider-trigger-executor.test.ts > the kernel executes compiled 'app_mention' subscriptions with provider isolation and durable dedupe
 FAIL  tests/provider-trigger-executor.test.ts > the kernel executes compiled 'reaction_added' subscriptions with provider isolation and durable dedupe
 FAIL  tests/provider-trigger-executor.test.ts > the kernel executes compiled 'pull_request' subscriptions with provider isolation and durable dedupe
Error: spawnSync /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/debug/relayflowd ENOENT
 ❯ submit tests/provider-trigger-executor.test.ts:43:89
     41|     steps: [{ id: 'effect', type: 'deterministic', command: `printf ac…
     42|   }))));
     43|   const submit = (envelope: unknown, key: string, executor = source.na…
       |                                                                                         ^
     44|     '--data-dir', dir, 'run', spec, '--event', JSON.stringify({ type: …
     45|   ], { encoding: 'utf8', stdio: 'pipe' })) as { matched: boolean; dedu…
 ❯ tests/provider-trigger-executor.test.ts:50:12

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[13/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage input validation > refuses an 8-character run-id prefix: Cloud has no prefix lookup
AssertionError: expected [Function] to throw error matching /not full Cloud run ids: c649fe14/ but got 'expected an @relayflows/surface flow …'

- Expected: 
/not full Cloud run ids: c649fe14/

+ Received: 
"expected an @relayflows/surface flow handle"

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[14/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage input validation > refuses the whole batch when any id is invalid, rather than dropping it
AssertionError: expected [Function] to throw error matching /not full Cloud run ids: nope!/ but got 'expected an @relayflows/surface flow …'

- Expected: 
/not full Cloud run ids: nope!/

+ Received: 
"expected an @relayflows/surface flow handle"

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[15/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage input validation > refuses an empty batch
AssertionError: expected [Function] to throw error matching /needs runIds/ but got 'expected an @relayflows/surface flow …'

- Expected: 
/needs runIds/

+ Received: 
"expected an @relayflows/surface flow handle"

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[16/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage input validation > refuses a batch too large for the edge step lease
AssertionError: expected [Function] to throw error matching /exceeds the 8 that fit/ but got 'expected an @relayflows/surface flow …'

- Expected: 
/exceeds the 8 that fit/

+ Received: 
"expected an @relayflows/surface flow handle"

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[17/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage input validation > accepts eight ids — the incident batch is inside the bound
AssertionError: promise rejected "TypeError: expected an @relayflows/surfac…" instead of resolving
 ❯ tests/stuck-run-triage.test.ts:62:40
     60|   it('accepts eight ids — the incident batch is inside the bound', asy…
     61|     const ids = Array.from({ length: 8 }, (_, i) => `${ID_A.slice(0, -…
     62|     await expect(drive({ runIds: ids })).resolves.toBeDefined();
       |                                        ^
     63|   });
     64| });

Caused by: TypeError: expected an @relayflows/surface flow handle
 ❯ Module.getFlowDefinition ../surface/src/flow.ts:143:11
 ❯ drive tests/stuck-run-triage.test.ts:34:9
 ❯ tests/stuck-run-triage.test.ts:62:18

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[18/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage apiUrl > refuses to send the Cloud bearer token to an unapproved origin
AssertionError: expected [Function] to throw error matching /refusing to send the Cloud bearer to…/\ but got 'expected an @relayflows/surface flow …'

- Expected: 
/refusing to send the Cloud bearer token to https:\/\/evil\.example/

+ Received: 
"expected an @relayflows/surface flow handle"

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[19/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage apiUrl > refuses a non-URL apiUrl
AssertionError: expected [Function] to throw error matching /is not a URL/ but got 'expected an @relayflows/surface flow …'

- Expected: 
/is not a URL/

+ Received: 
"expected an @relayflows/surface flow handle"

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[20/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage apiUrl > allows an approved origin and uses it in the curl
TypeError: expected an @relayflows/surface flow handle
 ❯ Module.getFlowDefinition ../surface/src/flow.ts:143:11
 ❯ drive tests/stuck-run-triage.test.ts:34:9
     32|     done: () => {},
     33|   };
     34|   await getFlowDefinition<StuckRunTriageInput>(triage).body(f as never…
       |         ^
     35|   return rec;
     36| }
 ❯ tests/stuck-run-triage.test.ts:77:23

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[21/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage apiUrl > defaults to production Cloud
TypeError: expected an @relayflows/surface flow handle
 ❯ Module.getFlowDefinition ../surface/src/flow.ts:143:11
 ❯ drive tests/stuck-run-triage.test.ts:34:9
     32|     done: () => {},
     33|   };
     34|   await getFlowDefinition<StuckRunTriageInput>(triage).body(f as never…
       |         ^
     35|   return rec;
     36| }
 ❯ tests/stuck-run-triage.test.ts:82:23

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[22/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage apiUrl > never publishes a run record the fetch did not produce
TypeError: expected an @relayflows/surface flow handle
 ❯ Module.getFlowDefinition ../surface/src/flow.ts:143:11
 ❯ drive tests/stuck-run-triage.test.ts:34:9
     32|     done: () => {},
     33|   };
     34|   await getFlowDefinition<StuckRunTriageInput>(triage).body(f as never…
       |         ^
     35|   return rec;
     36| }
 ❯ tests/stuck-run-triage.test.ts:89:34

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[23/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage edge collection > names the Worker on every wrangler invocation
TypeError: expected an @relayflows/surface flow handle
 ❯ Module.getFlowDefinition ../surface/src/flow.ts:143:11
 ❯ drive tests/stuck-run-triage.test.ts:34:9
     32|     done: () => {},
     33|   };
     34|   await getFlowDefinition<StuckRunTriageInput>(triage).body(f as never…
       |         ^
     35|   return rec;
     36| }
 ❯ tests/stuck-run-triage.test.ts:98:33

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[24/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage edge collection > accepts caller-supplied Workers and rejects option-shaped ones
TypeError: expected an @relayflows/surface flow handle
 ❯ Module.getFlowDefinition ../surface/src/flow.ts:143:11
 ❯ drive tests/stuck-run-triage.test.ts:34:9
     32|     done: () => {},
     33|   };
     34|   await getFlowDefinition<StuckRunTriageInput>(triage).body(f as never…
       |         ^
     35|   return rec;
     36| }
 ❯ tests/stuck-run-triage.test.ts:107:33

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[25/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage edge collection > falls back when GNU timeout is absent, as it is on macOS
TypeError: expected an @relayflows/surface flow handle
 ❯ Module.getFlowDefinition ../surface/src/flow.ts:143:11
 ❯ drive tests/stuck-run-triage.test.ts:34:9
     32|     done: () => {},
     33|   };
     34|   await getFlowDefinition<StuckRunTriageInput>(triage).body(f as never…
       |         ^
     35|   return rec;
     36| }
 ❯ tests/stuck-run-triage.test.ts:115:33

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[26/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage edge collection > runs the tails concurrently so wall time does not scale with the batch
TypeError: expected an @relayflows/surface flow handle
 ❯ Module.getFlowDefinition ../surface/src/flow.ts:143:11
 ❯ drive tests/stuck-run-triage.test.ts:34:9
     32|     done: () => {},
     33|   };
     34|   await getFlowDefinition<StuckRunTriageInput>(triage).body(f as never…
       |         ^
     35|   return rec;
     36| }
 ❯ tests/stuck-run-triage.test.ts:123:33

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[27/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage edge collection > records wrangler's own exit status rather than head's
TypeError: expected an @relayflows/surface flow handle
 ❯ Module.getFlowDefinition ../surface/src/flow.ts:143:11
 ❯ drive tests/stuck-run-triage.test.ts:34:9
     32|     done: () => {},
     33|   };
     34|   await getFlowDefinition<StuckRunTriageInput>(triage).body(f as never…
       |         ^
     35|   return rec;
     36| }
 ❯ tests/stuck-run-triage.test.ts:129:33

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[28/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage shell text > parses under both sh and bash
TypeError: expected an @relayflows/surface flow handle
 ❯ Module.getFlowDefinition ../surface/src/flow.ts:143:11
 ❯ drive tests/stuck-run-triage.test.ts:34:9
     32|     done: () => {},
     33|   };
     34|   await getFlowDefinition<StuckRunTriageInput>(triage).body(f as never…
       |         ^
     35|   return rec;
     36| }
 ❯ tests/stuck-run-triage.test.ts:137:23

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[29/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage shell text > collects tails with no GNU timeout on PATH, as on a stock macOS
TypeError: expected an @relayflows/surface flow handle
 ❯ Module.getFlowDefinition ../surface/src/flow.ts:143:11
 ❯ drive tests/stuck-run-triage.test.ts:34:9
     32|     done: () => {},
     33|   };
     34|   await getFlowDefinition<StuckRunTriageInput>(triage).body(f as never…
       |         ^
     35|   return rec;
     36| }
 ❯ tests/stuck-run-triage.test.ts:157:33

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[30/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage agents > declares read-only permissions on every agent
TypeError: expected an @relayflows/surface flow handle
 ❯ Module.getFlowDefinition ../surface/src/flow.ts:143:11
 ❯ drive tests/stuck-run-triage.test.ts:34:9
     32|     done: () => {},
     33|   };
     34|   await getFlowDefinition<StuckRunTriageInput>(triage).body(f as never…
       |         ^
     35|   return rec;
     36| }
 ❯ tests/stuck-run-triage.test.ts:176:23

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[31/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage agents > tells the forensics agents their evidence is untrusted
TypeError: expected an @relayflows/surface flow handle
 ❯ Module.getFlowDefinition ../surface/src/flow.ts:143:11
 ❯ drive tests/stuck-run-triage.test.ts:34:9
     32|     done: () => {},
     33|   };
     34|   await getFlowDefinition<StuckRunTriageInput>(triage).body(f as never…
       |         ^
     35|   return rec;
     36| }
 ❯ tests/stuck-run-triage.test.ts:182:23

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[32/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage fan-out > refuses a duplicate run id: two tails would share one evidence file
AssertionError: expected [Function] to throw error matching /duplicate runIds: c649fe14-0c2e-4e51-…/ but got 'expected an @relayflows/surface flow …'

- Expected: 
/duplicate runIds: c649fe14-0c2e-4e51-9a6a-4f0d1b0f77aa/

+ Received: 
"expected an @relayflows/surface flow handle"

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[33/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage fan-out > refuses a duplicate Worker name for the same reason
AssertionError: expected [Function] to throw error matching /duplicate workers: w-one/ but got 'expected an @relayflows/surface flow …'

- Expected: 
/duplicate workers: w-one/

+ Received: 
"expected an @relayflows/surface flow handle"

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[34/43]⎯

 FAIL  tests/stuck-run-triage.test.ts > stuck-run-triage fan-out > bounds ids x workers, not just ids
AssertionError: expected [Function] to throw error matching /24 concurrent tails, over the 16/ but got 'expected an @relayflows/surface flow …'

- Expected: 
/24 concurrent tails, over the 16/

+ Received: 
"expected an @relayflows/surface flow handle"

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[35/43]⎯

 FAIL  tests/webhook-live.test.ts > executes and deduplicates 'app_mention' only for its provider and matching payload
 FAIL  tests/webhook-live.test.ts > executes and deduplicates 'reaction_added' only for its provider and matching payload
 FAIL  tests/webhook-live.test.ts > executes and deduplicates 'pull_request' only for its provider and matching payload
Error: webhook integration timed out: spawn /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/debug/relayflowd ENOENT
 ❯ until tests/webhook-live.test.ts:39:9
     37|   const deadline = Date.now() + 10_000;
     38|   while (Date.now() < deadline) { if (await predicate()) return; await…
     39|   throw new Error(`webhook integration timed out: ${detail()}`);
       |         ^
     40| }
     41| async function daemon(dir: string): Promise<ChildProcess> {
 ❯ daemon tests/webhook-live.test.ts:43:3
 ❯ tests/webhook-live.test.ts:100:3

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[36/43]⎯

 FAIL  tests/webhook-live.test.ts > flows serve-webhook writes JSON before the daemon starts, then journals and archives exactly once
Error: webhook integration timed out: spawn /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/debug/relayflowd ENOENT
 ❯ until tests/webhook-live.test.ts:39:9
     37|   const deadline = Date.now() + 10_000;
     38|   while (Date.now() < deadline) { if (await predicate()) return; await…
     39|   throw new Error(`webhook integration timed out: ${detail()}`);
       |         ^
     40| }
     41| async function daemon(dir: string): Promise<ChildProcess> {
 ❯ daemon tests/webhook-live.test.ts:43:3
 ❯ tests/webhook-live.test.ts:121:3

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[37/43]⎯

 FAIL  tests/webhook-live.test.ts > replays a dropped file after SIGKILL before spawn
Error: webhook integration timed out: spawn /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/debug/relayflowd ENOENT
 ❯ until tests/webhook-live.test.ts:39:9
     37|   const deadline = Date.now() + 10_000;
     38|   while (Date.now() < deadline) { if (await predicate()) return; await…
     39|   throw new Error(`webhook integration timed out: ${detail()}`);
       |         ^
     40| }
     41| async function daemon(dir: string): Promise<ChildProcess> {
 ❯ daemon tests/webhook-live.test.ts:43:3
 ❯ tests/webhook-live.test.ts:137:17

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[38/43]⎯

 FAIL  tests/webhook-live.test.ts > resumes the same journal after SIGKILL after spawn and before acknowledgement
Error: webhook integration timed out: spawn /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/debug/relayflowd ENOENT
 ❯ until tests/webhook-live.test.ts:39:9
     37|   const deadline = Date.now() + 10_000;
     38|   while (Date.now() < deadline) { if (await predicate()) return; await…
     39|   throw new Error(`webhook integration timed out: ${detail()}`);
       |         ^
     40| }
     41| async function daemon(dir: string): Promise<ChildProcess> {
 ❯ daemon tests/webhook-live.test.ts:43:3
 ❯ tests/webhook-live.test.ts:150:17

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[39/43]⎯

⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯

Vitest caught 1 unhandled error during the test run.
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.

⎯⎯⎯⎯⎯ Uncaught Exception ⎯⎯⎯⎯⎯
Error: spawn /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/release/relayflowd ENOENT
 ❯ Process.ChildProcess._handle.onexit node:internal/child_process:285:19
 ❯ onErrorNT node:internal/child_process:483:16
 ❯ processTicksAndRejections node:internal/process/task_queues:90:21

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { errno: -2, code: 'ENOENT', syscall: 'spawn /home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/release/relayflowd', path: '/home/daytona/.relayflow-v2-supervisor/durable/repository/kernel/target/release/relayflowd', spawnargs: [ '--data-dir', '/tmp/flows-mcp-daemon-MGnwpD', 'serve' ] }
This error originated in "tests/mcp.test.ts" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.
The latest test that might've caused the error is "authored MCP effects against the real kernel". It might mean one of the following:
- The error was thrown, while Vitest was running this test.
- If the error occurred after the test had been completed, this was the last documented test before it was thrown.
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

 Test Files  7 failed | 148 passed | 3 skipped (158)
      Tests  41 failed | 2364 passed | 25 skipped (2430)
     Errors  1 error
   Start at  17:48:56
   Duration  205.51s (transform 2.13s, setup 0ms, collect 36.91s, tests 529.75s, environment 19ms, prepare 6.15s)


@khaliqgant

Copy link
Copy Markdown
Member

Supersession check — the upstream parity this PR anticipated has shipped

The PR body says: "Parity on issues/merge_requests is upstream @relayfile/relay-helpers work… a later upstream release must revisit this map deliberately." That release has now landed on main:

  • @relayfile/adapter-core@0.6.2 (published 2026-09-20) declares gitlab writeback paths for issues, merge-requests, merge, close-merge-request, and refs in WRITEBACK_PATH_CATALOG. Main's sdk already depends on 0.6.2.
  • @relayfile/adapter-gitlab@0.5.0 (published 2026-09-19) implements the writeback handlers: dist/writeback.js maps issues create (line 123, /api/v4/projects/.../issues), merge_requests (lines 149–173), comments and discussions create.
  • On main, gitlab is supported: true and f.gitlab.issues.list binds and dispatches through providerClient('gitlab') — keeping the 'partial' refusal would regress working dispatch.

This is the promotion the generator's comment describes — not merely a larger resource count: the adapter implements the named handlers. The branch's premise ("Issue list/read/create and merge-request list/read/create are unavailable through f.gitlab") was true at adapter-core 0.5.26 and is false at 0.6.2.

Two real findings from the adversarial review were also fixed on this branch meanwhile (head 2426a90f + merge 2b6a5b32, not yet pushed):

  1. P1 compile-against-published-surface: helper-preflight.ts now reads the catalog row structurally; tsc --noEmit passes against the published @relayflows/surface@2.0.22 tarball (exit 0).
  2. P2 scanner gaps: rebindsIdentifier now sees destructured declarations (const { f } =, const [f] =) and object/class method parameters (read(f) {}), verified by mutation test (new regressions fail on revert, pass restored) — 13/13 helper-partial-support tests pass.

If the coordinator/product call is that gitlab parity stands, this PR's feature is fully superseded and the right terminal state is close-with-evidence (the partial machinery would be dead code — no partial provider remains). If a mount-level check shows upstream gitlab writeback is NOT actually served, the branch is repaired and ready to proceed on its own merits. Holding the push pending that call.

@khaliqgant khaliqgant changed the title Software factory change f.gitlab is comment-only while f.github has full writeback, and the provider catalog marks both supported: true Sep 23, 2026
`typecheck:regressions` failed with TS2578: the `@ts-expect-error` on
`f.gitlab.issues.list` was unused, because the helper namespace is structural
and the call does typecheck.

That is the design, not a gap. gitlab is `supported: "partial"` with
resources comments and discussions, and the catalog refuses the rest at
runtime with a named member, its resource and the available names --
`f.gitlab.issues is unavailable; available resources: comments, discussions.`
-- covered across dot, bracket and aliased access in helper-support.test.ts
and the SDK's helper-partial-support.test.ts.

The directive claimed a type-level narrowing that was never implemented, so
the file asserted something untrue and the compiler said so. The
`mergeRequests` case stays: that member genuinely does not exist on the type,
and removing its directive still raises TS2551.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@khaliqgant

Copy link
Copy Markdown
Member

Pushed 4632825, which fixes the TS2578: Unused '@ts-expect-error' half of packed-consumer: the directive on f.gitlab.issues.list asserted a type-level narrowing this design does not make — the helper namespace is structural, so the call typechecks and the refusal is a runtime one. The mergeRequests directive stays and still raises TS2551 when removed.

The remaining failure is a design contradiction, not a test problem, so I have not touched it.

packed-consumer also runs check-generated-helpers.mjs, which reports:

Error: Generated helpers drifted: gitlab.ts, providers.ts.
Run npm run gen --prefix packages/surface

src/helpers/providers.ts and src/helpers/gitlab.ts are generated files, and this branch hand-edited them to say gitlab is comment-only. Running the generator reverts that:

- * Available resources: comments, discussions.
+ * Available resources: close-merge-request, comments, discussions, issues, merge, merge-requests, refs.

The runtime failures in this job agree with the generator rather than the branch — the refusal raises Ambiguous writeback resource "issues", not f.gitlab.issues is unavailable, i.e. gitlab's writeback catalog does carry issues, ambiguously.

So the branch's premise and its source of truth disagree, and only one can be right:

  1. gitlab really is comment-only → the catalog the generator reads is wrong and should be corrected there, after which regenerating produces the branch's intended output and the tests pass as written.
  2. gitlab has those resources → the ticket's premise is outdated, and the fix is to resolve the Ambiguous writeback resource "issues" ambiguity rather than to declare the namespace comment-only.

Regenerating to make CI green would silently choose (2) and revert this PR's whole point, so I stopped here. This needs the author's call.

The other failing check, linux-x64-artifact, flaked on unrelated PRs earlier today and is worth a re-run once the above is settled.

Adopt shipped GitLab writeback parity, keep the generated provider catalog reviewable, make helper-reference analysis scope-aware for destructured and method bindings, and refresh the hosted Surface byte review.

Session-Id: 01a0d52d-03d5-7773-b760-d6b67d5d8235
@khaliqgant khaliqgant changed the title f.gitlab is comment-only while f.github has full writeback, and the provider catalog marks both supported: true Expose helper resource catalogs and honor shadowed context bindings Sep 24, 2026
@khaliqgant

Copy link
Copy Markdown
Member

Shepherd note: exact-head repair is edd8c44, main e04c5b9. Packed/validate/guard are green; linux run 36058867396 remains pending. Once terminal, obtain a fresh independent review pinned to edd8c44 before any draft/ready transition.

@khaliqgant khaliqgant left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Independent exact-head review of edd8c44. Guarded repair is based on current main e04c5b9; SDK typecheck and typecheck:tests pass, helper fanout suite 96/96 passes. Required checks are terminal green: linux 36058867396, packed 36058867409, validate 36058867400, guard 36058862811; Cubic and CodeRabbit statuses pass. No substantive blocker found in the focused helper-support/generator changes. Draft remains intentionally unchanged for owner/product completion.

@khaliqgant
khaliqgant marked this pull request as ready for review September 25, 2026 03:42
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-25T03:46:28.556458Z edd8c44 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@khaliqgant
khaliqgant marked this pull request as draft September 25, 2026 03:45

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: edd8c44a60

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/sdk/src/helper-reference.ts Outdated
Comment thread packages/sdk/src/helper-reference.ts Outdated

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread packages/sdk/src/helper-reference.ts Outdated
Session-Id: 01a0d6ad-a1bd-78b0-9284-d13e4db53e96
Session-Id: 01a0d6ad-a1bd-78b0-9284-d13e4db53e96

@khaliqgant khaliqgant left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

NO-GO at exact head 53a10fd7df74b1fd5cdea7d0283de561c0011104.

[P1] Keep root-flow parameter defaults visible — packages/sdk/src/helper-reference.ts:142

The new parameterHidden = shadowed || bindsParameter hides every parameter subtree on the root function because the root context parameter itself necessarily binds f. Later root parameter defaults may legitimately read the already-initialized context parameter, so (f, x = f.gitlab.issues) => x really uses GitLab. At this head the scanner reports no helper and preflight admits the flow without a GitLab mount, moving a provable failure to runtime. Nested functions whose own parameter list binds f should remain hidden; the root function is the exception.

Literal reproduction:

bun -e <probe importing packages/sdk/src/helper-preflight.ts and evaluating the three bodies below>
{"name":"rootDefault","kinds":[]}
{"name":"nestedDefault","kinds":["helper_provider.mount_required"]}
{"name":"nestedBound","kinds":[]}

The probe bodies were:

(f, x = f.gitlab.issues) => x
(f) => { function read(x = f.gitlab.issues) { var f = local; return f.gitlab; } }
(f) => { const g = (f, x = f.gitlab.issues) => x; return g; }

The second and third results are correct; the first must contain helper_provider.mount_required.

Focused exact-head verification otherwise passed:

mise x node@22.23.2 -- npx vitest run tests/helper-reference.test.ts tests/helpers-fanout.test.ts
Test Files  2 passed (2)
Tests  125 passed (125)

mise x node@22.23.2 -- npm run typecheck --prefix packages/sdk
@relayflows/sdk@2.0.32 typecheck
tsc --noEmit && tsc -p tsconfig.type-tests.json

mise x node@22.23.2 -- npm run typecheck:tests --prefix packages/sdk
@relayflows/sdk@2.0.32 typecheck:tests
tsc -p tsconfig.tests.json

Main 979325af5cb59ff9b4892cacdeb58e1a10f700c3 is an ancestor of this head. At capture time validate and guard were green; linux-x64-artifact and packed-consumer were still in progress. Even if those finish green, this preflight miss blocks approval. Add the root-default regression and keep its parameter initializer traversal unshadowed before requesting a fresh exact-head review.

Session-Id: 01a0d6ad-a1bd-78b0-9284-d13e4db53e96

@khaliqgant khaliqgant left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

APPROVE — independently reviewed exact head 28c46e45b64d658a59e6cec0d9fabb1bd81c4d2f.

Main 979325af5cb59ff9b4892cacdeb58e1a10f700c3 is an ancestor. The root parameter-default regression is fixed: (f, x = f.gitlab.issues) => x now reports helper_provider.mount_required; nested parameter/default and function-scoped var cases remain correctly scoped.

Literal focused verification:

npx vitest run tests/helper-reference.test.ts tests/helpers-fanout.test.ts
Test Files  2 passed (2)
Tests  126 passed (126)

npm run typecheck --prefix packages/sdk
tsc --noEmit && tsc -p tsconfig.type-tests.json

npm run typecheck:tests --prefix packages/sdk
tsc -p tsconfig.tests.json

Exact-head required checks:

guard pass
validate pass
packed-consumer pass
linux-x64-artifact pass
npm/pages skipped by workflow

All substantive review threads are outdated against this head and their findings are covered by the binding-position/default-expression, nested-var, and root-default fixes. Mergeability is CLEAN/MERGEABLE. Draft/readiness state remains unchanged; I did not mark ready, merge, or mutate repository files.

@miyaontherelay
miyaontherelay marked this pull request as ready for review September 25, 2026 04:24
@miyaontherelay
miyaontherelay merged commit 3d7216e into main Sep 25, 2026
9 checks passed

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 28c46e4. Configure here.

hidden = true;
} else if (node.type === 'CatchClause' && isNode(node.param) && patternBinds(node.param, root)) {
hidden = true;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

For-loop bindings skip shadowing

Low Severity

The new scope walk hides block, catch, and function bindings of the context name, but a for / for-in / for-of head that lexically binds that name still counts member access in the loop as an outer helper reference. Preflight can then demand a mount the flow never uses.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 28c46e4. Configure here.

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.

3 participants