refactor(cli): enforce Effect platform boundaries#3859
Closed
Alberto Schiabel (jkomyno) wants to merge 53 commits into
Closed
refactor(cli): enforce Effect platform boundaries#3859Alberto Schiabel (jkomyno) wants to merge 53 commits into
Alberto Schiabel (jkomyno) wants to merge 53 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
|
The Please review and fix the vulnerabilities. You can try running: pnpm audit --fix --prodAudit output |
This comment was marked as outdated.
This comment was marked as outdated.
Route cached-schema decoding and validation errors through Effect Schema, prevent direct Zod imports in the validator, and reuse the CLI autocorrect distance with bounded suggestions.
Replace private tag and descriptor inspection with public Effect APIs, model expected failures as typed errors, and decode untrusted runtime data at schema boundaries. Preserve the behavior with focused regression coverage and CLI migration guidance.
…eterministic clock Un-ignore ts/packages/cli/test (fixtures and the test/__utils__ harness glue stay unlinted) and ban Effect.run* and Date.now() in test sources: Effects run through @effect/vitest (it.effect / it.scoped / it.live) so failures surface as typed Exits, and time is pinned via TestClock-relative fixtures, vi.setSystemTime, or crypto.randomUUID() for unique names. Migrate the ~90 existing Effect.run* call sites across 18 suites, strengthen throw-based failure assertions to typed error checks, relax max-lines-per-function and no-explicit-any for test code, and fix a raw ESC control byte that made one suite unparseable.
…ffect idioms Consolidate repeated concepts across ts/packages/cli/src/services into single canonical definitions, verified behavior-preserving: - export JsonRecordSchema from effects/json and drop 9 local re-declarations - share checksum parsing/hashing (utils/checksums), djb2 (utils/djb2), and the tolerant per-entry cache decode (utils/collect-decoded-entries) - reuse toolkitFromToolSlug, compareNewestFirst, hasEnvPrefix, detectMaster, and getAncestors instead of inline re-implementations - delete the orphaned EnvLangDetector service (superseded by ProjectEnvironmentDetector, zero consumers) - extract sortBySlug, filterBySlugPrefixes, toSetupTargetResult, runSetupTargets, getFreshCacheEntry, and DEFAULT_CLI_USER_CONFIG to unify copy-pasted blocks - convert ToolInputValidationError to Data.TaggedError (same tag/message), narrow two catchAll recoveries to catchTag, derive the connected-account status list from the model schema - tool-input-validation: fetch tool detail and latest version concurrently, reuse the fetched definition on the stale path instead of re-reading the cache file, and drop exists-then-read/remove TOCTOU checks Verified: pnpm typecheck, pnpm lint, CLI vitest (916 passed), pnpm build.
…cross CLI source Convert every node:path usage behind a no-restricted-imports disable to the @effect/platform Path service: plain path helpers become Effects where their callers are Effect-hosted (getAncestors, safeOutputPath, cachePath), sync boundaries receive the Path.Path instance as a plain parameter (ts.CompilerHost, promise-queue cache helpers), and self-provided layer stacks gain Path.layer. run-companion-modules.ts is fully Effect-ified over FileSystem/Path/Config, dropping its fs/os/path import disables and the process.env/try-finally syntax disables with behavior parity.
…ct idioms Convert the remaining fixable disables: try/catch JSON and URL probes become Either.try helpers (parseJsonRecord for user-supplied flag payloads), promise-queue cache and upload helpers receive a threaded FileSystem instance (write queue now serialized by a module-level semaphore), update-check is Effect-ified end to end behind its single pre-runtime runPromiseExit boundary, upgrade-binary uses FileSystem copy/remove, and the no-explicit-any and max-lines-per-function disables are removed with precise types and mechanical helper extraction.
…ble manifest Every eslint-disable in CLI src must be a single-line disable with a reason and be registered in eslint-boundaries.json with an exact per-file, per-rule count; validate-eslint-boundaries.ts (wired into pnpm test, so CI-blocking) rejects anything else. Document the boundary policy — service table, conversion patterns, sanctioned runtime boundaries, manifest ritual — in AGENTS.md and the cli-command skill reference.
…latform-guardrails
The suite landed on next before this branch's lint rule banning Effect.run* in CLI tests; the PR merge combines both, so convert the two cases to it.effect with the decode-ignoring effect yielded directly.
This was referenced Jul 17, 2026
Collaborator
Author
|
Closing in favor of a reviewable stack that reproduces this branch's final tree (the
The only intentional content deviation from this branch's tip: the stack drops |
Alberto Schiabel (jkomyno)
added a commit
that referenced
this pull request
Jul 21, 2026
…ups (#3877) This PR: - opens the CLI Effect-guardrails stack that re-slices #3859 into reviewable PRs - rewrites the CLI `AGENTS.md` Effect guidance: typed `Data.TaggedError` failures, `Schema`/`Predicate` decoding at trust boundaries, and Effect platform services over Node builtins — policy for new code effective now - adds the matching "Effect Platform Boundaries" section to the `cli-command` skill reference - defines every new ESLint rule group (platform imports, terminal streams, descriptor seam, zod ban, test rules, try/catch + `process.env`) as live constants in the root `eslint.config.mjs`, with the entries applying them commented out and annotated with the stack PR that activates each group - bumps the vendored `ts/vendor/effect` reference to the pin used across the stack (CI never initializes submodules) No CLI source is touched; `pnpm lint` stays green with the rules inert. --- **Stack** (re-slice of #3859; each PR targets its parent and auto-retargets to `next` as parents merge): 1. #3877 — guidelines + inert rule groups ← **this PR** 2. #3878 — `new Function()` eval security fix 3. #3879 — behavioral fix pack 4. #3880 — platform-imports rule + migration 5. #3881 — terminal-streams rule + TerminalUI boundary 6. #3882 — descriptor seam + zod→Schema 7. #3883 — test-tree lint + deterministic suites 8. #3884 — typed error boundaries + v4 seams 9. #3885 — try/catch+env ban + boundary ratchet On stacked bases CI runs lint/build and the CLI Docker e2e job; unit tests and typecheck are verified locally per PR and re-verified by full CI when each PR is retargeted to `next`.
Alberto Schiabel (jkomyno)
added a commit
that referenced
this pull request
Jul 21, 2026
…3878) This PR: - removes an in-process arbitrary-code-execution surface: `parse-json-ish.ts` fell back to `Function("return (…)")()` for any `tools execute --data`, `listen --params`, or `proxy` body value that failed JSON and comment-JSON parsing — the CLI is agent-facing and `--data` also accepts `@file` and stdin, so crafted or prompt-injected input reached the eval - lands the parser in its final consolidated shape: `src/utils/parse-json.ts` parses JSON5 (unquoted keys, single quotes, trailing commas, comments) without evaluating anything and returns `Either` with a typed `JsonParsingError` - consolidates the `effect-errors` read-json duplicates onto the same parser and swaps `comment-json` for `json5` (the stack's only lockfile change) - pins code-execution probes in unit tests (`new Date()`, computed expressions, `globalThis` writes are rejected, never evaluated) - intentional narrowing: JS expressions such as `1+1` that only worked because of the eval now fail with a parse error; proxy bodies that are not JSON5 records fall back to the raw string --- **Stack** (re-slice of #3859; each PR targets its parent and auto-retargets to `next` as parents merge): 1. #3877 — guidelines + inert rule groups 2. #3878 — `new Function()` eval security fix ← **this PR** 3. #3879 — behavioral fix pack 4. #3880 — platform-imports rule + migration 5. #3881 — terminal-streams rule + TerminalUI boundary 6. #3882 — descriptor seam + zod→Schema 7. #3883 — test-tree lint + deterministic suites 8. #3884 — typed error boundaries + v4 seams 9. #3885 — try/catch+env ban + boundary ratchet On stacked bases CI runs lint/build and the CLI Docker e2e job; unit tests and typecheck are verified locally per PR and re-verified by full CI when each PR is retargeted to `next`.
Alberto Schiabel (jkomyno)
added a commit
that referenced
this pull request
Jul 21, 2026
…#3879) This PR: - lands ten behavioral fixes as one commit each, so `git show` reviews standalone - fails the tool-permission gate closed: an unknown snapshot state or a failed policy resolve on a controls-enabled org now synthesizes an `ask_every_call` snapshot (never persisted) instead of silently skipping the gate, and interactive approval UI never spawns where nobody can answer it (CI/Vitest) - surfaces realtime subscription failures as typed errors: `composio listen` prints one actionable line mentioning `composio login`, cleans up temporary triggers, and exits 1 instead of dumping a captured defect - tolerates newer connected-account payloads with a fallback decode whose field allowlist keeps credential-bearing fields (`state`, `data`) out of `link --list` output - decodes persisted caches and GitHub release listings per entry, so one corrupt or version-skewed entry drops only itself - extracts API error details field by field, renders the deepest cause in pretty errors, and accepts `null` optional strings in agent API responses --- **Stack** (re-slice of #3859; each PR targets its parent and auto-retargets to `next` as parents merge): 1. #3877 — guidelines + inert rule groups 2. #3878 — `new Function()` eval security fix 3. #3879 — behavioral fix pack ← **this PR** 4. #3880 — platform-imports rule + migration 5. #3881 — terminal-streams rule + TerminalUI boundary 6. #3882 — descriptor seam + zod→Schema 7. #3883 — test-tree lint + deterministic suites 8. #3884 — typed error boundaries + v4 seams 9. #3885 — try/catch+env ban + boundary ratchet On stacked bases CI runs lint/build and the CLI Docker e2e job; unit tests and typecheck are verified locally per PR and re-verified by full CI when each PR is retargeted to `next`.
Alberto Schiabel (jkomyno)
added a commit
that referenced
this pull request
Jul 21, 2026
…3880) This PR: - activates the platform-imports rule group: `node:fs`, `node:path`, `node:os`, and `child_process` are now ESLint-banned in CLI source - migrates ~36 files to `FileSystem`/`Path`/`Command` from `@effect/platform`, introducing the `NodeOs` and `DetachedProcess` service boundaries and Effect-native run-companion module resolution - keeps the sanctioned permanent boundaries (`node-os.ts`, `detached-process.ts`, `run-subagent-output-mcp.ts`, `cli-user-config.ts`, the child-process companion runtime) on inline `-- reason` disables - files whose compliant rewrite belongs to a later slice carry temporary inline disables naming the owning PR; a small sync bridge in `run-companion-modules.ts` keeps the not-yet-migrated Promise-based callers working until the typed-error slice removes it - adds A-theme coverage: `NodeOs` platform info through Effect, session artifacts via `FileSystem` with symlink and HOME-less handling, skill-root discovery, and safe-output-path traversal guards --- **Stack** (re-slice of #3859; each PR targets its parent and auto-retargets to `next` as parents merge): 1. #3877 — guidelines + inert rule groups 2. #3878 — `new Function()` eval security fix 3. #3879 — behavioral fix pack 4. #3880 — platform-imports rule + migration ← **this PR** 5. #3881 — terminal-streams rule + TerminalUI boundary 6. #3882 — descriptor seam + zod→Schema 7. #3883 — test-tree lint + deterministic suites 8. #3884 — typed error boundaries + v4 seams 9. #3885 — try/catch+env ban + boundary ratchet On stacked bases CI runs lint/build and the CLI Docker e2e job; unit tests and typecheck are verified locally per PR and re-verified by full CI when each PR is retargeted to `next`. ## Review follow-up - `DetachedProcess` now waits for Node’s `spawn` or `error` event, so ENOENT/EACCES become typed failures instead of false success; focused tests cover failure and success. - the platform-import rule now rejects bare `fs`, `fs/*`, `os`, and `path` specifiers as well as their `node:` forms; the two exposed path imports now use Effect `Path`. - run-companion self-repair again honors unprefixed `GITHUB_*` values first, with `COMPOSIO_GITHUB_*` fallback and regression coverage for both contracts. Verification: CLI tests (95 files, 834 passed, 1 skipped), workspace TypeScript typecheck, scoped ESLint (0 errors), CLI build, Prettier, and `git diff --check`.
Alberto Schiabel (jkomyno)
added a commit
that referenced
this pull request
Jul 21, 2026
…3881) This PR: - activates the terminal-streams rule group: `process.stdout`/`process.stderr` are now ESLint-banned in CLI source, with `services/terminal-ui.ts` as the sole stream boundary (that file is itself held to the try/catch + `process.env` restrictions early) - extends `TerminalUI` with `capabilities` (TTY/interactivity/decoration detection) and a raw `error()` writer, replacing `utils/stdio.ts` (deleted) - makes analytics dispatch Effect-native and delivers detached telemetry through `DetachedProcess`, staying non-fatal on failure - consolidates runtime debug logging into a `RuntimeDebugLogger` service and rebuilds `cli-main` around `showUpdateNotice`/telemetry as Effects with errors reported via `ui.error` - the update checker reads terminal capabilities from the service and keeps its fire-and-forget contract --- **Stack** (re-slice of #3859; each PR targets its parent and auto-retargets to `next` as parents merge): 1. #3877 — guidelines + inert rule groups 2. #3878 — `new Function()` eval security fix 3. #3879 — behavioral fix pack 4. #3880 — platform-imports rule + migration 5. #3881 — terminal-streams rule + TerminalUI boundary ← **this PR** 6. #3882 — descriptor seam + zod→Schema 7. #3883 — test-tree lint + deterministic suites 8. #3884 — typed error boundaries + v4 seams 9. #3885 — try/catch+env ban + boundary ratchet On stacked bases CI runs lint/build and the CLI Docker e2e job; unit tests and typecheck are verified locally per PR and re-verified by full CI when each PR is retargeted to `next`.
Alberto Schiabel (jkomyno)
added a commit
that referenced
this pull request
Jul 21, 2026
#3882) This PR: - activates the descriptor-seam rule group: `commands/command-introspection.ts` becomes the only module allowed to import `CommandDescriptor`/`Usage` from `@effect/cli` — the redesign seam the Effect CLI v4 migration will reimplement - routes root command assembly, preflight parsing, help routing, and value-option collection through the seam helpers instead of descriptor walks - replaces the Zod-backed tool-input adapter with an internal `@composio/json-schema-to-effect-schema` compiler backed by the eval-free `@cfworker/json-schema` interpreter - normalizes the OpenAPI and Composio extensions accepted by the previous validator, while preserving typed `ToolInputValidationError` failures, field paths, multi-error reporting, and typo suggestions - extends the descriptor and Zod boundaries to reject static imports, dynamic `import()`, and `require()` bypasses - adds compiler parity tests plus CLI regression coverage for multiple simultaneous field and unknown-key failures - introspection tests pin that the helpers yield identical descriptors and usage strings --- **Stack** (re-slice of #3859; each PR targets its parent and auto-retargets to `next` as parents merge): 1. #3877 — guidelines + inert rule groups 2. #3878 — `new Function()` eval security fix 3. #3879 — behavioral fix pack 4. #3880 — platform-imports rule + migration 5. #3881 — terminal-streams rule + TerminalUI boundary 6. #3882 — descriptor seam + Zod→Schema ← **this PR** 7. #3883 — test-tree lint + deterministic suites 8. #3884 — typed error boundaries + v4 seams 9. #3885 — try/catch+env ban + boundary ratchet On stacked bases CI runs lint/build and the CLI Docker e2e job; unit tests and typecheck are verified locally per PR and re-verified by full CI when each PR is retargeted to `next`.
Alberto Schiabel (jkomyno)
added a commit
that referenced
this pull request
Jul 21, 2026
…t suites (#3883) This PR: - un-ignores `ts/packages/cli/test` in the root ESLint config (fixtures and the `test/__utils__` harness glue stay unlinted) and activates the test rule group: no `Effect.run*` in suites (use `it.effect`/`it.scoped`/`it.live`) and no `Date.now()` - adds `test/__utils__/vitest.setup.ts`, pointing HOME and `COMPOSIO_CACHE_DIR` at per-run temp directories so suites never touch the developer's real `~/.composio` state - migrates the remaining suites onto @effect/vitest runners with layer-provided platforms, pins wall-clock reads via `vi.setSystemTime`/TestClock-relative fixtures, and uses `crypto.randomUUID()` for unique temp names - lands the v3 Cause characterization suite pinning `reduceWithContext` traversal over the six-constructor tree and rendered error output — the executable equivalence oracle for the effect v4 migration - tests arriving in later stack PRs must comply from birth --- **Stack** (re-slice of #3859; each PR targets its parent and auto-retargets to `next` as parents merge): 1. #3877 — guidelines + inert rule groups 2. #3878 — `new Function()` eval security fix 3. #3879 — behavioral fix pack 4. #3880 — platform-imports rule + migration 5. #3881 — terminal-streams rule + TerminalUI boundary 6. #3882 — descriptor seam + zod→Schema 7. #3883 — test-tree lint + deterministic suites ← **this PR** 8. #3884 — typed error boundaries + v4 seams 9. #3885 — try/catch+env ban + boundary ratchet On stacked bases CI runs lint/build and the CLI Docker e2e job; unit tests and typecheck are verified locally per PR and re-verified by full CI when each PR is retargeted to `next`.
Alberto Schiabel (jkomyno)
added a commit
that referenced
this pull request
Jul 21, 2026
… seams (#3884) This PR: - converts every remaining thunk-form `Effect.tryPromise` in CLI source to a purpose-named `Data.TaggedError` preserving its cause — `UnknownException` no longer surfaces from `src/` — and switches best-effort recoveries from `catchAll` to `catchTag` - isolates the `Symbol.for('effect/SpanAnnotation')` internal read behind a shape-validating adapter, with a canary test that fails a real effect through the runtime so an `effect` upgrade that drops the mechanism breaks CI instead of silently losing span timelines - decodes trigger-log payloads once at the API boundary through a tolerant schema documenting camelCase/snake_case/meta-nested alias precedence - deduplicates the per-entry tolerant decoders into `utils/collect-decoded-entries.ts`, replaces locally re-declared record schemas with `JsonRecordSchema`, deletes the unused `EnvLangDetector` service, and removes the temporary sync bridge from the platform-imports slice - the largest PR of the stack by design: generic refactors land late so the fix and rule slices before it stay small; one commit per sub-theme keeps `git show` reviewable --- **Stack** (re-slice of #3859; each PR targets its parent and auto-retargets to `next` as parents merge): 1. #3877 — guidelines + inert rule groups 2. #3878 — `new Function()` eval security fix 3. #3879 — behavioral fix pack 4. #3880 — platform-imports rule + migration 5. #3881 — terminal-streams rule + TerminalUI boundary 6. #3882 — descriptor seam + zod→Schema 7. #3883 — test-tree lint + deterministic suites 8. #3884 — typed error boundaries + v4 seams ← **this PR** 9. #3885 — try/catch+env ban + boundary ratchet On stacked bases CI runs lint/build and the CLI Docker e2e job; unit tests and typecheck are verified locally per PR and re-verified by full CI when each PR is retargeted to `next`.
Alberto Schiabel (jkomyno)
added a commit
that referenced
this pull request
Jul 21, 2026
…y ratchet (#3885) This PR: - activates the final rule group: `TryStatement` and `process.env` are now ESLint-banned in CLI source, completing the enforcement ramp started in the first PR of this stack; the env guard covers dot access, bracket access, and object destructuring - migrates the residual files (auth-config create, trigger create, toolkit search, runtime debug flags, master detection, import-time UI setup) off try/catch and ad-hoc env reads - every surviving violation sits at a declared runtime boundary (bin.ts bootstrap, child-process companion runtime, import-time UI setup, environment writes and whole-environment enumeration, spawn-time env handshakes) with an inline `// eslint-disable-next-line <rule> -- <reason>` justification - adds `eslint-boundaries.json` — the checked-in manifest of the 46 sanctioned disables across 22 files — and `validate:boundaries` (part of `pnpm test`), which scans both `.ts` and `.tsx` sources and fails on undeclared, missing, relocated, bare, or file-wide disables - pins each registered boundary by rule, justification, and governed next-line target, with regression coverage for TSX discovery, same-file retargeting, and duplicate semantic sites - documents the Effect Boundary Policy in the CLI `AGENTS.md` and the `cli-command` skill reference, and drops the gitleaks test-file allowlist --- **Stack** (re-slice of #3859; each PR targets its parent and auto-retargets to `next` as parents merge): 1. #3877 — guidelines + inert rule groups 2. #3878 — `new Function()` eval security fix 3. #3879 — behavioral fix pack 4. #3880 — platform-imports rule + migration 5. #3881 — terminal-streams rule + TerminalUI boundary 6. #3882 — descriptor seam + zod→Schema 7. #3883 — test-tree lint + deterministic suites 8. #3884 — typed error boundaries + v4 seams 9. #3885 — try/catch+env ban + boundary ratchet ← **this PR** On stacked bases CI runs lint/build and the CLI Docker e2e job; unit tests and typecheck are verified locally per PR and re-verified by full CI when each PR is retargeted to `next`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR:
try/catchblocks and directnode:fs,node:os, ornode:pathimports in CLI production sourcesFileSystem,Path, layers, and typed recoverySecond slice: Effect v4 readiness
Symbol.for('effect/SpanAnnotation')internal read behind a shape-validating adapter, with a canary test that fails a real effect through the runtime so aneffectupgrade that drops the mechanism breaks CI instead of silently losing span timelinesreduceWithContextover the six-constructor tree) and rendered error output with characterization tests, giving the v4 migration an executable equivalence oracleEffect.tryPromisesites to typedData.TaggedErrorfailures that preserve their cause;UnknownExceptionno longer enters the CLI error channel fromsrc/, and best-effort recoveries switch fromcatchAlltocatchTagSecond slice: boundary and correctness fixes
parse-json-ish.tsfell back tonew Function()evaluation for anytools execute --data,listen --params, orproxybody value that failed JSON and comment-JSON parsing — an in-process arbitrary-code-execution surface. The CLI is agent-facing and--dataalso accepts@fileand stdin, so crafted or prompt-injected input reached the eval. Replaced with JSON5, which covers the documented "JSON or JS-style object literal" contract (unquoted keys, single quotes, trailing commas, comments) without evaluating anything; code-execution probes are now pinned by unit tests. Intentional narrowing: genuine JS expressions (1+1,new Date()) that only worked because of the eval now fail with a parse error.composio listenandcomposio dev triggers listenno longerEffect.orDieexpected network/auth failures into captured-defect dumps; they print one actionable line ("Could not subscribe to realtime trigger events: … Check your network connection or runcomposio login."), clean up temporary triggers, and exit 1Schema.transformthat documents the camelCase/snake_case/meta-nested alias precedence, replacingas unknown as Recordcast ladders duplicated acrossformat.tsandlogs.triggers.cmd.ts; raw payloads still go to stdout unchangedCommandDescriptor/Usageintrospection intocommand-introspection.ts— the @effect/cli v4 redesign seam — so the v4 command-tree rewrite touches one module; ano-restricted-importsrule keeps the seam sealedValidation
pnpm typecheck- 12/12 tasks passedpnpm --filter @composio/cli test- 889 passed, 1 skippedpnpm --filter @composio/cli build- passedgit diff --check- passedNew concepts
ESLint bulk-suppression ratchet
ESLint records the current violation count for each file and rule. A later change fails lint when it adds a violation, and cleanup also fails until the now-stale count is pruned.
That lets this PR activate strict Effect boundaries immediately without adding roughly 92 inline disable comments or forcing an all-at-once rewrite of the CLI. The migrated telemetry, artifact, and config paths reduce those baseline counts as part of the same change.
The tradeoff is identity: counts are not tied to exact source locations, so replacing one legacy violation with another in the same file can remain green. This is a migration tool, not the end state; the baseline should disappear as the remaining files move to Effect Platform.
Third slice: fail-closed gating and tolerant decoding
gateToolExecutionskipped entirely, silently executing tools the org policy may explicitly deny (always_deny). The gate now fails closed with evidence: a failed policy resolve on a controls-enabled org synthesizes anask_every_callsnapshot (never persisted to cache), so the worst case is a spurious prompt instead of an unauthorized side-effecting tool call. A failed org-config probe still skips the gate — it carries no evidence controls exist, and prompting there would break older backends and offline runs.message, stringcode) drops only itself instead of discarding the node's validslugandrequest_idcomposio upgradeor the background update check, and skipped entries are loggedcausemessage as aCaused by:line in pretty error output, so wrappers likeUpgradeBinaryErrorno longer swallow the actionable ParseError specificsifthat could silently skip*.test.tsallowlist from.gitleaks.toml(added alongside per-fingerprint suppressions that already covered the findings; CI has since moved to GitHub Advanced Security, so the rule only disarmed local and future gitleaks runs)Validation for this slice:
pnpm typecheckpasses; clean-environment full CLI suite — 908 passed, 1 skipped.Related: #3832 (merged separately) makes
whoamireport the org selected viaorgs switchinstead of the API key's home org.