Skip to content

Add entitlement approval gate for task classes - #923

Merged
sroussey merged 4 commits into
mainfrom
claude/agent-review-migration-8elz3s
Sep 8, 2026
Merged

Add entitlement approval gate for task classes#923
sroussey merged 4 commits into
mainfrom
claude/agent-review-migration-8elz3s

Conversation

@sroussey

@sroussey sroussey commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Introduces a static approval rule for task classes, and makes this package's RAG tasks declare the knowledge base they reach so the rule has something to read.

Why here rather than downstream

The entitlement taxonomy says what a task reaches. It has never answered the question a host actually asks it — given this class, must a person approve before it runs — so every host wanting a gate writes its own, downstream, against a taxonomy that grows here. An id added here inherits a pass from a list nobody downstream remembers to widen. That direction is the bug.

The rule

EntitlementApproval.ts exports INFERENCE_ENTITLEMENTS, entitlementsBeyond, taskClassReach, taskClassNeedsApproval and describeTaskClassReach.

  • Matching is exact, not hierarchical, even though entitlementCovers sits next door and looks like the natural choice. An ai:autonomous-egress id minted later must gate the tasks declaring it rather than inherit a pass from an ambient ai. Fail-closed on a new capability is the point.
  • A class that cannot be asked for its declaration reads as unknown and gates. Catalogs populate taskClass by cast, so one without the static is reachable; calling through unguarded crashed inside the approval path, and defaulting to an empty list is worse — indistinguishable from a task that genuinely reaches nothing.
  • An optional entitlement is kept and rendered may use network:http. This parts company with evaluatePolicy deliberately: that decides whether to allow a run and may ignore reach a task degrades without; this decides what to tell a person before they approve.

entitlementsFromChildren, and what it is not

New static on Task (false) / GraphAsTask (true). It means reach not knowable until run time — the subgraph a GraphAsTask is handed.

It is deliberately not hasDynamicEntitlements, which reads like the same question. A task is dynamic when it refines what it already declaresAiTask sets it to attach the resolved model id to ai:model. 43 tasks in builder's catalog set that flag, every AI task among them; gating on it puts an approval in front of running a model at all.

It is also not set on the five run-time composers in this package (AiChatWithKbTask, ChunkRetrievalTask, ContextBuilderTask, DocumentEnricherTask, HierarchicalChunkerTask). They own fixed, hard-coded children — a TextEmbeddingTask, a CountTokensTask — so their reach is knowable from their own source. Flagging them would print "not declared up front" about a known child set, which is the same misleading prompt in the other direction. They declare the union instead.

The case that motivated it

In the first consumer (workglow-dev/builder#461), six tasks in the system catalog are composed — GraphAsTask, FallbackTask, MapTask, WhileTask, ReduceTask — and each declared nothing statically, so a downstream gate read the empty set as "reaches nothing". A MapTask skill ran whatever subgraph an LLM handed it without asking.

Then the same question turned on this package and found the mirror image: AiTask was the only class in packages/ai/src/task/ overriding entitlements(), and no task anywhere in the repo declared storage:* — the taxonomy had it, EntitlementProfiles granted it, nothing asked for it. taskClassNeedsApproval(KbDeleteTask) returned false, and describeTaskClassReach said "reaches nothing", for a task whose execute() calls kb.delete().

Ten classes now declare what they touch, pinned by tests.

Correction, kept visible

Two of those declarations were wrong in an earlier commit on this branch and are fixed in f2b9ebc. Both came from sweeping for kb.<method>( and matching call-shaped text that was not a call:

  • ChunkRetrievalTask was given storage:write for "installing a text index on first hybrid search". It does not. It names installTextIndex inside an error message and never calls it; that method assigns a field rather than touching storage; and hybridSearch throws without an index rather than installing one. It declares storage:read.
  • TextRerankerTask was given storage:read. It reaches no knowledge base at all — its ports are query, documents, topK, model, and the only kb. in the file is a comment noting a KB invokes this task. Its override is removed and it is ungated.

Over-declaring costs what under-declaring costs: a prompt saying a reranker touches storage is one people learn to click through, and then the KbDeleteTask prompt stops nobody either. Every remaining declaration was re-checked against an awaited call.

VectorSimilarityTask also now extends Task. It used nothing from GraphAsTask and an earlier commit overrode the inherited composed answer to correct it; reparenting makes the wrong answer unrepresentable and drops two more inherited claims (hasDynamicSchemas, hasDynamicEntitlements) equally untrue of it.

Downstream

workglow-dev/builder#461 consumes these exports and is red until this merges and a release ships — its catalog pins =0.4.8. Merge here → release → bump the pin there.

Verification

  • bun scripts/test.ts ai rag task-graph entitlement unit vitest — 176 files, 1,743 passed, 0 failed
  • bun run lint (type-aware, --deny-warnings) and bun run format-check — clean
  • bun scripts/test.ts --check-sections — new test files reachable by section+kind selection

Run on Node 22.22.2, one below the repo's declared floor of 24; storage-backed sections were left unrun for that reason.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JEFYAGb9D3mWfyhYkmeAvN

The entitlement taxonomy says what a task reaches. It has never answered the
question a host actually asks it — given this class, must a person approve
before it runs — so every host wanting a gate writes its own, downstream,
against a taxonomy that grows here. An id added here would inherit a pass
from a list nobody downstream remembers to widen.

Written as an allowlist: INFERENCE_ENTITLEMENTS names the three ids a caller
already running a model necessarily holds; everything else is reach it does
not otherwise have. Matching is exact rather than hierarchical even though
entitlementCovers sits next door and looks like the natural choice — an
ambient `ai` must not silently cover an `ai:*` id minted after the fact.

The case worth the file is the second one: an empty static declaration is
not always about the task. A composed task computes its aggregate on the
INSTANCE, so a graph wrapping a URL fetcher declares nothing and a
class-only check certifies it as pure.

That needed a fact this library did not state, so it now does.
`entitlementsFromChildren` is false on Task and true on GraphAsTask, which
every composed task inherits. It is deliberately NOT hasDynamicEntitlements,
which reads like the same question and is not: a task is dynamic when it
refines what it already declares, and every AI task sets it in order to
attach the resolved model id to `ai:model`. Keying the gate on that flag
puts an approval in front of running a model at all — the one thing a caller
holding INFERENCE_ENTITLEMENTS was always going to do. Both readings are
pinned by tests so the distinction cannot quietly collapse.

describeTaskClassReach gives an approval prompt its one line, and reports a
composed class as undeclared rather than as reaching nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JEFYAGb9D3mWfyhYkmeAvN
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 55.24% 40370 / 73070
🔵 Statements 54.71% 42336 / 77370
🔵 Functions 56.02% 7880 / 14064
🔵 Branches 44.35% 20956 / 47251
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/task-graph/src/task/Task.ts 55% 45.23% 52.45% 56.4% 994-996, 140-156, 180-198, 238-246, 269, 289-307, 315-332, 346, 347, 362, 437, 503, 520-523, 534, 545-556, 569, 575-582, 588, 593, 599-601, 619, 625-635, 642-643, 656-670, 682-686, 705, 728-735, 753-755, 773, 789-790, 804, 808-814, 830, 833, 837, 844-847, 871-880, 904, 921-922, 929-938, 954-973, 995-1035, 1048-1052
Generated in workflow #3430 for commit ce41fe3 by the Vitest Coverage Report Action

…ss also declares

Review of the previous commit found two ways the approval prompt could still
read as a complete answer when it is not.

describeTaskClassReach chose between the declared list and the "reach lives in
its children" caveat, so a composed class that ALSO declares something static
printed only its wrapper's share — the same misleading reading as reporting the
empty set, in a second spelling. The caveat is now appended rather than chosen
between, and the emptiness test reads the reach array rather than the joined
string so it cannot disagree with taskClassNeedsApproval about a class whose
entitlement renders blank.

VectorSimilarityTask extends GraphAsTask for its runner and config shape but
computes in process and never runs a subgraph, so it inherited the composed
answer and would have drawn a confirmation card describing tasks that do not
exist. It declares entitlementsFromChildren = false.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JEFYAGb9D3mWfyhYkmeAvN
The approval gate reads a task class's declaration, and almost nothing in
this package declares. AiTask was the only class here overriding
entitlements(), and no task anywhere in the repo claimed storage:* — the
taxonomy had it and the profiles granted it, but nothing asked for it. So
taskClassNeedsApproval answered false for KbDeleteTask: a skill that wipes
a document and its chunks, behind a card reading "reaches nothing".

Eleven classes now declare what they touch. ChunkRetrievalTask declares
storage:write as well as read, because installTextIndex writes an index on
the first hybrid search; the two AI-base subclasses merge with super rather
than replacing, since entitlements() overrides rather than extends.

The five run-time composers are deliberately NOT marked
entitlementsFromChildren. They own fixed, hard-coded children — a
TextEmbeddingTask, a CountTokensTask — so their reach is knowable from their
own source, and the flag means the opposite: not knowable until run time.
Setting it there would print "not declared up front" about a known child
set, which is the same misleading prompt in the other direction. They
declare the union instead, and Task's JSDoc now says which case the flag is
for.

Three gate fixes ride along. A class that cannot be asked for its
declaration — catalogs populate taskClass by cast, so one without the static
is reachable — was calling through unguarded, crashing inside the approval
path; it now reads as unknown and gates, rather than as empty and passing.
The "nothing" line is phrased against the ambient set rather than against
inference, since that set is a parameter and a caller passing its own was
told a class reaches nothing beyond running a model it never runs. An
optional entitlement renders as "may use": it is kept rather than skipped,
which is where this parts company with evaluatePolicy on purpose — that
decides whether to allow a run, this decides what to tell a person first.

VectorSimilarityTask now extends Task. It used nothing from GraphAsTask and
overrode the composed answer to correct it; reparenting makes the wrong
answer unrepresentable and drops two more inherited claims (dynamic schemas,
dynamic entitlements) that were equally untrue of it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JEFYAGb9D3mWfyhYkmeAvN
Both came from sweeping for `kb.<method>(` and matching call-shaped text that
was not a call.

ChunkRetrievalTask does not write. It names installTextIndex once, inside an
error message telling the caller how to fix a missing text index, and never
calls it — and that method assigns a field rather than touching storage
anyway. hybridSearch throws when no index is installed rather than lazily
installing one; the index auto-writes happen on chunk upsert, and existing
chunks are not back-indexed without an explicit reindexText. It searches, so
it declares storage:read alone.

TextRerankerTask reaches no knowledge base at all. Its input ports are
query, documents, topK and model; the only `kb.` in the file is a comment
noting that a knowledge base invokes THIS task, so the dependency runs the
other way. Its declaration is removed entirely, leaving the ai:inference its
base class declares — and leaving it ungated, which is right for a task that
scores strings with a model.

Over-declaring costs what under-declaring costs. A prompt that says a
reranker touches storage is a prompt people learn to click through, and then
the KbDeleteTask prompt does not stop anyone either.

Every remaining declaration was re-checked against an awaited call rather
than a grep hit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JEFYAGb9D3mWfyhYkmeAvN
@sroussey
sroussey merged commit e967d9d into main Sep 8, 2026
15 checks passed
@sroussey
sroussey deleted the claude/agent-review-migration-8elz3s branch September 8, 2026 19:50
sroussey added a commit that referenced this pull request Sep 8, 2026
## @workglow/browser-control

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/task-graph

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

#### task-graph

- add entitlement approval gate for ai task classes (#923)

### Bug Fixes

#### task-graph

- move `runPreview`'s return out of the `finally` block (#918)

#### web-search

- name a credential for a provider, fill Brave's open date bound, and thread abort
- resolve the search credential once, in the task that sends it

### Chores

- revert version change not made by bunset

## @workglow/javascript

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/web-search

### Features

#### web-search

- add OpenAI, OpenRouter and Gemini grounded providers
- add runtime entries, registration and README
- add SearXNG provider with a keyless live test
- add Tavily provider with native filters and answers
- add Brave provider over an owned FetchUrlTask
- add WebSearchTask with pinned and routed provider selection
- add provider registry with capability routing
- translate domain filters to site: operators
- add provider interface and capability check

### Bug Fixes

#### web-search

- refuse a domain entry that names no domain
- address code review across the package and its adapters
- honour or refuse a named credential, stop registering providers on import, and keep two ports honest
- name a credential for a provider, fill Brave's open date bound, and thread abort
- let a provider declare that it takes one domain list, not both
- make maxResults mean the same thing for every provider
- resolve the search credential once, in the task that sends it
- make the instance entitlements reachable and fail closed
- keep test declarations out of the published tarball
- correct rate-limiter claim and gate the grounded answer
- remove quadratic backtracking from trailing-slash trim

### Documentation

- document @workglow/web-search in CLAUDE.md

### Chores

#### web-search

- bring the new package up to the workspace conventions

## @workglow/ai

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

#### task-graph

- add entitlement approval gate for ai task classes (#923)

### Bug Fixes

#### pricing

- various fixes for pricing on models
- merge a declared rate card over the provider's field by field
- resolve rates from the live table and at the request's instant

### Chores

- revert version change not made by bunset

## @workglow/knowledge-base

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## workglow

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/storage

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Bug Fixes

#### postgres

- give a vector storage a real pgvector column

#### storage

- stop connection transactions hanging and leaking uncommitted rows

### Refactors

#### storage

- route the tx handle through the public methods

### Chores

- revert version change not made by bunset

## @workglow/mcp

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

- route human-in-the-loop tasks to the MCP client
- serve registered tasks over MCP, behind a bearer token

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Bug Fixes

- keep server-side failure detail off the wire
- make the bearer and tool-name parsers linear
- close the gaps a review of the MCP server turned up

### Chores

- revert version change not made by bunset

## @workglow/triggers

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/util

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Bug Fixes

#### util

- repair the Node worker path and drop the Bun worker fork

### Chores

- revert version change not made by bunset

## @workglow/test

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Bug Fixes

- file the human-in-the-loop tasks under "Human", not "Flow Control"

#### util

- repair the Node worker path and drop the Bun worker fork

#### postgres

- give a vector storage a real pgvector column

#### release

- gate publish-all on tests again (#916)

#### pricing

- various fixes for pricing on models
- resolve rates from the live table and at the request's instant

#### storage

- stop connection transactions hanging and leaking uncommitted rows
- guard updateWhere's primary key on the transaction path

### Refactors

#### storage

- route the tx handle through the public methods

### Tests

#### pricing

- assert the billing unit in the contract suite, off the same fixtures

### Chores

- revert version change not made by bunset
- update bunset and its configuration and dependencies

### Updated Dependencies

- `miniflare`: ^5.20260908.0-alpha

## @workglow/tasks

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Bug Fixes

- file the human-in-the-loop tasks under "Human", not "Flow Control"

### Chores

- revert version change not made by bunset

## @workglow/job-queue

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/indexeddb

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/openai

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

#### web-search

- add OpenAI, OpenRouter and Gemini grounded providers

### Bug Fixes

#### web-search

- address code review across the package and its adapters
- honour or refuse a named credential, stop registering providers on import, and keep two ports honest
- name a credential for a provider, fill Brave's open date bound, and thread abort
- make maxResults mean the same thing for every provider

#### pricing

- resolve rates from the live table and at the request's instant

#### openrouter,openai

- resolve the search API key explicitly and lazily

### Chores

- revert version change not made by bunset

## @workglow/llamacpp-server

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/mlx

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Bug Fixes

#### pricing

- various fixes for pricing on models

### Chores

- revert version change not made by bunset

## @workglow/electron

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/ollama

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/node-llama-cpp

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/aws

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/anthropic

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

#### anthropic

- add grounded web-search provider subpath

### Bug Fixes

#### web-search

- address code review across the package and its adapters
- honour or refuse a named credential, stop registering providers on import, and keep two ports honest
- name a credential for a provider, fill Brave's open date bound, and thread abort
- let a provider declare that it takes one domain list, not both
- make maxResults mean the same thing for every provider
- keep test declarations out of the published tarball
- correct rate-limiter claim and gate the grounded answer

#### pricing

- resolve rates from the live table and at the request's instant

#### anthropic

- give the package a test script so its tests actually run

### Documentation

- document @workglow/web-search in CLAUDE.md

### Chores

- revert version change not made by bunset

## @workglow/duckdb

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Bug Fixes

#### storage

- stop connection transactions hanging and leaking uncommitted rows

### Refactors

#### storage

- route the tx handle through the public methods

### Chores

- revert version change not made by bunset

## @workglow/google-gemini

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

#### web-search

- add OpenAI, OpenRouter and Gemini grounded providers

### Bug Fixes

#### web-search

- address code review across the package and its adapters
- honour or refuse a named credential, stop registering providers on import, and keep two ports honest
- name a credential for a provider, fill Brave's open date bound, and thread abort
- make maxResults mean the same thing for every provider

#### pricing

- various fixes for pricing on models
- resolve rates from the live table and at the request's instant

### Chores

- revert version change not made by bunset

## @workglow/postgres

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Bug Fixes

#### postgres

- give a vector storage a real pgvector column

#### storage

- stop connection transactions hanging and leaking uncommitted rows
- guard updateWhere's primary key on the transaction path

### Refactors

#### storage

- route the tx handle through the public methods

### Chores

- revert version change not made by bunset

## @workglow/stable-diffusion-server

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/supabase

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/xai

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Bug Fixes

#### pricing

- various fixes for pricing on models
- resolve rates from the live table and at the request's instant

### Chores

- revert version change not made by bunset

## @workglow/deepseek

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Bug Fixes

#### pricing

- resolve rates from the live table and at the request's instant

### Chores

- revert version change not made by bunset

## @workglow/playwright

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/sqlite

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Bug Fixes

#### storage

- stop connection transactions hanging and leaking uncommitted rows
- guard updateWhere's primary key on the transaction path

### Refactors

#### storage

- route the tx handle through the public methods

### Chores

- revert version change not made by bunset

## @workglow/cloudflare

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/huggingface-transformers

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/tf-mediapipe

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/chrome-ai

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Bug Fixes

#### pricing

- various fixes for pricing on models

### Chores

- revert version change not made by bunset

## @workglow/openrouter

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

#### web-search

- add OpenAI, OpenRouter and Gemini grounded providers

### Bug Fixes

#### web-search

- address code review across the package and its adapters
- honour or refuse a named credential, stop registering providers on import, and keep two ports honest
- name a credential for a provider, fill Brave's open date bound, and thread abort
- make maxResults mean the same thing for every provider

#### pricing

- various fixes for pricing on models

#### openrouter,openai

- resolve the search API key explicitly and lazily

### Chores

- revert version change not made by bunset

## @workglow/huggingface-inference

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/cactus

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/bun-webview

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset

## @workglow/eval

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Bug Fixes

#### util

- repair the Node worker path and drop the Bun worker fork

#### pricing

- resolve rates from the live table and at the request's instant

### Chores

- revert version change not made by bunset
- update bunset and its configuration and dependencies

### Updated Dependencies

- `hyparquet`: ^1.30.0

## @workglow/cli

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

- route human-in-the-loop tasks to the MCP client
- serve registered tasks over MCP, behind a bearer token

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

#### cli

- mark what an `all` command actually runs, and give a command group its own page in the web console

### Bug Fixes

- close the gaps a review of the MCP server turned up
- file the human-in-the-loop tasks under "Human", not "Flow Control"

#### util

- repair the Node worker path and drop the Bun worker fork

#### pricing

- various fixes for pricing on models
- merge a declared rate card over the provider's field by field
- resolve rates from the live table and at the request's instant

#### cli/web

- share one status-rail read instead of tearing down under it

### Chores

- revert version change not made by bunset

## @workglow/web

### Breaking Changes

- **features(storage)**: add join() to ITabularStorage with SQL pushdown (#893)

### Features

#### storage

- add join() to ITabularStorage with SQL pushdown (#893)

### Chores

- revert version change not made by bunset
- update bunset and its configuration and dependencies

### Updated Dependencies

- `react-resizable-panels`: ^4.12.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants