Skip to content
Merged
2 changes: 1 addition & 1 deletion apps/hub/src/hub-error-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { makeErrorEnvelope } from "@corbits/error-sink";
* Duck-typed rather than an `instanceof` allowlist: any error carrying a
* string `guidance` alongside its `message` is a named, consumer-facing
* failure the thrower already wrote for a human to read — see
* `@corbits/folded-runs`'s `DefinitionProjectionMissingError` and
* `@corbits/workflows`'s `DefinitionProjectionMissingError` and
* `MultiStepFoldUnsupportedError`. Its `message` is safe to return
* verbatim; anything else is a platform fault whose internals must not
* leak to a client.
Expand Down
22 changes: 11 additions & 11 deletions apps/hub/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -757,17 +757,17 @@ export async function createHub(config: HubConfig) {
},
};
const hubPublicKey = hexEncode(signingKey.publicKey);
// CL-6149: a folded run's pinned tool packages (`toolPackagePins`)
// carry no grants of their own — the deploy-time capability walk
// CL-6149: a launch's pinned tool packages (`toolPackagePins`) carry
// no grants of their own — the deploy-time capability walk
// (`vendor/intx/workflow-deploy/src/capability-walk.ts`) only derives
// `tool:` grants for inline tool factories, so a pinned package's
// tools failed every call closed with "No matching grants". Every
// `@corbits/*-tools` package's namespaced tool ids and approval marks
// are read once here (`describeCorbitsToolPackages`), so
// `toolGrantsForPins` — the port every `FoldedRunsDeps` below is
// built with — can synchronously turn a launch's pins into the
// `tool:<qualifiedId>` grants `@corbits/folded-runs`' `deployAtHead`
// mints against the run's own principal.
// `toolGrantsForPins` — the port `createHubChatPlatform`'s
// `CreateHubChatPlatformDeps` is built with — can synchronously turn a
// launch's pins into the `tool:<qualifiedId>` grants minted against
// the run's own principal.
const toolGrantsForPins = createToolGrantsForPins(
await describeCorbitsToolPackages(),
);
Expand Down Expand Up @@ -2800,11 +2800,11 @@ export async function createHub(config: HubConfig) {
// down immediately — never a resident that outlives the request, so no
// idle-sleep lifecycle is needed for it.

// Every genuine top-level deployment run, folded runs (workbench hosts,
// invited agents) excluded — the scoped listing CL-6061 adds
// so the Agent Directory and the shell's "Running" bands stop
// deriving that exclusion client-side from a tenant's workbenches alone
// (see `@corbits/folded-runs`'s `scope-routes.ts`, which a folded run
// Every genuine top-level deployment run, workbench-hosted and invited-agent
// runs excluded — the scoped listing CL-6061 adds so the Agent Directory
// and the shell's "Running" bands stop deriving that exclusion
// client-side from a tenant's workbenches alone (see
// `@corbits/run-scope`'s `scope-routes.ts`, which a non-top-level run
// with no workbench involved silently slipped past).
app.route(
`${TENANT_PREFIX}/top-level-runs`,
Expand Down
7 changes: 4 additions & 3 deletions apps/hub/src/mcp-credential-bindings.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// The `McpCredentialBindingsFor` port every `FoldedRunsDeps` below is wired
// with — see `@corbits/folded-runs`' `types.ts` for why this has to be
// supplied by the composition root rather than derived by the deploy-time
// The `McpCredentialBindingsFor` port `createHubChatPlatform`'s
// `CreateHubChatPlatformDeps` is wired with — see `@corbits/chat`'s
// `platform-adapter.ts` for why this has to be supplied by the
// composition root rather than derived by the deploy-time
// capability walk. `@corbits/mcp-tools`' credential handles are dynamic
// (one `mcp.<slug>` per tenant-connected server), so this builds one
// `CredentialBinding` per connection `@corbits/connections`' own
Expand Down
12 changes: 6 additions & 6 deletions apps/hub/src/native-workflow-routine-launch.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Routes a multi-step routine definition onto Interchange's native
// workflow-run trigger primitive instead of `@corbits/folded-runs`'
// workflow-run trigger primitive instead of `@corbits/workflows`'
// single-step fold.
//
// A multi-step `workflow_definition` can only exist in this repo as a
// code-sourced `@intx/workflow` package deployed through
// `POST /workflows/deployments`
// (`vendor/intx/hub-api/src/routes/workflows.ts`, backed by
// `sessionService.deployWorkflowFromSource`) — `@corbits/folded-runs`'
// `sessionService.deployWorkflowFromSource`) — `@corbits/workflows`'
// `readFoldedBody` throws `MultiStepFoldUnsupportedError` for exactly
// this reason (see `packages/folded-runs/src/definition.ts`): its
// deploy target, `@corbits/agent-runtime`'s single-turn
// this reason (see `packages/workflows/src/definition-projection.ts`):
// its deploy target, `@corbits/agent-runtime`'s single-turn
// `AgentRuntimeConfig`, has no notion of step order, so folding a
// multi-step body into it would silently run step one and drop the
// rest. Since a code-sourced deploy is the ONLY way a multi-step
Expand All @@ -23,8 +23,8 @@
// public surface, so the message is assembled here from the same
// public `@intx/mime`/`@intx/crypto` primitives it uses, and delivered
// through `SidecarRouter.routeMail` — a public method every
// `FoldedRunsDeps` caller (including the routine launcher) already
// holds.
// `createHubChatPlatform` caller (including the routine launcher)
// already holds.
//
// Grant authorization for this mail-triggered run is materialized by
// the vendored session orchestrator's own `mail.outbound` handler
Expand Down
7 changes: 4 additions & 3 deletions apps/hub/src/pinned-package-credential-bindings.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// The `PinnedPackageCredentialBindingsFor` port every `FoldedRunsDeps`
// below is wired with — see `@corbits/folded-runs`' `types.ts` for why
// this has to be supplied by the composition root rather than declared as
// The `PinnedPackageCredentialBindingsFor` port `createHubChatPlatform`'s
// `CreateHubChatPlatformDeps` is wired with — see `@corbits/chat`'s
// `platform-adapter.ts` for why this has to be supplied by the
// composition root rather than declared as
// a required assistant `credentialBindings` entry. Static-handle packages
// (`@corbits/manus-tools`, granola-tools, …) declare
// `interchange.credentials`, but requiring those binds on the assistant
Expand Down
4 changes: 1 addition & 3 deletions apps/hub/src/tool-grants.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// CL-6149: proves the hub's `toolGrantsForPins` port turns a launch's
// `toolPackagePins` into the exact `tool:<qualifiedId>` grants the
// workflow child's authz gate matches against — see
// `@corbits/folded-runs`' `deployAtHead`, which mints these into
// `config.grants`.
// workflow child's authz gate matches against.
import { describe, expect, test } from "bun:test";
import { describeCorbitsToolPackages } from "@corbits/tool-registry-publish";
import { createToolGrantsForPins } from "./tool-grants";
Expand Down
9 changes: 5 additions & 4 deletions apps/hub/src/tool-grants.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// CL-6149: a folded run's pinned tool packages (`toolPackagePins`) carry
// no grants of their own — the deploy-time capability walk
// CL-6149: a launch's pinned tool packages (`toolPackagePins`) carry no
// grants of their own — the deploy-time capability walk
// (`vendor/intx/workflow-deploy/src/capability-walk.ts`) only derives
// `tool:` grants for inline tool factories, so a pinned package's tools
// failed every call closed with "No matching grants". This builds the
// `ToolGrantsForPins` port every `FoldedRunsDeps` in this composition is
// wired with: given a launch's pins, look up each pin's package by name
// `ToolGrantsForPins` port `createHubChatPlatform`'s
// `CreateHubChatPlatformDeps` is wired with: given a launch's pins, look
// up each pin's package by name
// in the hub's own `describeCorbitsToolPackages()` read and mint one
// `tool:<qualifiedId>` / `invoke` declaration per tool, floored at `ask`
// for a tool the package itself marks `approval: "ask"`.
Expand Down
8 changes: 4 additions & 4 deletions apps/sidecar/src/workflow-host-wiring/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1653,10 +1653,10 @@ export function createSidecarDeployRouter(deps: {
*
* Returns `"deferred-to-wake"` instead of restoring for a single-step
* ("warm-keep") deployment (CL-6648): that shape is exactly what a
* folded run deploys, and folded runs already have a working lazy-wake
* port (`@corbits/agent-lifecycle`'s `ensureAwake` ->
* `@corbits/folded-runs`' `wakeFoldedRun` -> `deployAtHead`) that
* re-resolves inference sources fresh against the tenant's LIVE catalog
* chat launch deploys, and it already has a working lazy-wake port
* (`@corbits/agent-lifecycle`'s `ensureAwake` -> `@corbits/chat`'s
* `wakeByAddress` -> `prepareProvisionedDeployment`) that re-resolves
* inference sources fresh against the tenant's LIVE catalog
* on every wake -- `record.sources` is only ever a snapshot of what
* resolved at the deployment's last deploy or rotation. Restoring one
* eagerly here would instead replay that frozen snapshot forever,
Expand Down
6 changes: 3 additions & 3 deletions apps/sidecar/test/workflow-restore-defer-to-wake.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
// its last deploy or rotation. Restoring one eagerly from that snapshot
// at boot would replay a chain whose credential died after the freeze
// forever -- the deployment reads as "already live" to every later wake
// check, so the folded-run wake path (`ensureAwake` ->
// `wakeFoldedRun`/`deployAtHead`, which DOES re-resolve fresh against the
// live catalog on every call) never gets a chance to heal it.
// check, so the lazy-wake path (`ensureAwake` -> `@corbits/chat`'s
// `wakeByAddress`, which DOES re-resolve fresh against the live catalog
// on every call) never gets a chance to heal it.
//
// The fix: boot-time restore defers a single-step deployment to that
// wake path instead of restoring it from frozen sources -- proven here by
Expand Down
31 changes: 16 additions & 15 deletions apps/web/src/agents-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,15 @@ export function listAgentInstances(
}

/**
* The tenant's genuine top-level deployment runs — every folded run
* (workbench host, invited agent, routine fire, task) excluded server-side
* by the hub's own `folded_run` marker table (see `@corbits/folded-runs`'s
* `scope-routes.ts`), not derived client-side from a tenant's workbenches
* the way `foldedRunIdsFromWorkbenches` used to. Used wherever a page needs
* "real deployments only" — the Agent Directory. A routine fire IS a
* folded run, so this feed structurally never carries one; a caller that
* needs routine activity wants `listRoutineRunFires` below instead.
* The tenant's genuine top-level deployment runs — every non-top-level
* run (workbench host, invited agent, routine fire, task) excluded
* server-side by the same predicate `isTopLevelRun` uses (see
* `@corbits/run-scope`'s `scope-routes.ts`), not derived client-side
* from a tenant's workbenches the way `foldedRunIdsFromWorkbenches` used
* to. Used wherever a page needs "real deployments only" — the Agent
* Directory. A routine fire is NOT top-level, so this feed structurally
* never carries one; a caller that needs routine activity wants
* `listRoutineRunFires` below instead.
*/
export function listTopLevelRuns(
tenantId: string,
Expand All @@ -172,13 +173,13 @@ export function listTopLevelRuns(

/**
* `feed=fires` (CL-6249): the tenant's genuine *executed* runs — unlike
* `listTopLevelRuns`, a routine's fire is kept even though it is a folded
* run, tagged with the routine that fired it (see
* `@corbits/folded-runs`'s `scope-routes.ts`'s `listTopLevelRunFires`).
* `listTopLevelRuns`, a routine's fire is kept even though it is not a
* top-level run, tagged with the routine that fired it (see
* `@corbits/run-scope`'s `scope-routes.ts`'s `listTopLevelRunFires`).
* The shell's "Running" activity band (CL-6595) reads this, not
* `listTopLevelRuns`, so a routine's own run is actually visible here —
* `listTopLevelRuns`'s `notExists(folded_run)` filter drops every routine
* fire by construction, which left Mission Control's active-run count
* `listTopLevelRuns`'s top-level-only filter drops every routine fire by
* construction, which left Mission Control's active-run count
* permanently desynced from the Routines page's own "Running now" pill.
*/
export function listRoutineRunFires(
Expand Down Expand Up @@ -466,8 +467,8 @@ type SkillsOutcome =
* so either failing alone never blanks the page. Failures surface as
* `modelsError` / `skillsError` rather than silent empty collections.
* `instances` comes from `listTopLevelRuns`, which already excludes every
* folded run (workbench host, invited agent) server-side — see
* `@corbits/folded-runs`'s `scope-routes.ts` — so this page never has to
* non-top-level run (workbench host, invited agent) server-side — see
* `@corbits/run-scope`'s `scope-routes.ts` — so this page never has to
* derive that exclusion itself from a tenant's workbenches.
*/
export async function loadAgentDirectory(
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/agents-directory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ export function purposeAgentDefinitions(

/**
* `instances` is expected to already come from `listTopLevelRuns`
* (see `./agents-api.ts`), which excludes every folded run (workbench
* host, invited agent, task) server-side — see
* `@corbits/folded-runs`'s `scope-routes.ts`. This still applies the
* (see `./agents-api.ts`), which excludes every non-top-level run
* (workbench host, invited agent, task) server-side — see
* `@corbits/run-scope`'s `scope-routes.ts`. This still applies the
* shared name-based workbench-host filter as defense in depth.
*/
export function purposeAgentInstances(
Expand Down
8 changes: 4 additions & 4 deletions apps/web/src/insights-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// /scope is how a page discovers that shape to build a switcher.
// Plus one more reused as Insights' run feed: GET /top-level-runs?feed=fires
// → Paginated<WorkflowRunResponse & { routineId, routineName }>
// (packages/folded-runs/src/scope-routes.ts's `listTopLevelRunFires`).
// (packages/run-scope/src/scope-routes.ts's `listTopLevelRunFires`).

import { type } from "arktype";
import { WorkflowRunResponse, paginatedSchema } from "@intx/types";
Expand Down Expand Up @@ -259,10 +259,10 @@ const TOP_LEVEL_RUNS_LIMIT = 100;

/**
* Insights' run feed (CL-6062, `feed=fires` added by CL-6249): the
* tenant's genuine *executed* runs — a routine's fire (folded run though
* it is) included, and the resident, never-triggered deployment
* tenant's genuine *executed* runs — a routine's fire (not a top-level
* run though it is) included, and the resident, never-triggered deployment
* placeholder for a definition (`status: "deployed"` forever) excluded —
* both decided server-side by `@corbits/folded-runs`'s
* both decided server-side by `@corbits/run-scope`'s
* `scope-routes.ts`'s `listTopLevelRunFires`, never by a definitionName
* slug guess here. Used in place of the dead `/me/workflows/runs` — its
* `anchorRunId IS NULL` filter never matches, because every addressed run
Expand Down
15 changes: 8 additions & 7 deletions apps/web/src/insights-stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,13 @@ export const INSIGHTS_RECENT_LIMIT = 12;
/**
* Purpose runs only — drop workbench-host anchors the same way Home does.
* `insights-page.tsx` sources `runs` from `insightsTopLevelRunsPath` (see
* `./insights-api.ts`), which already excludes every folded run with no
* routine parent, and the resident never-fired deployment placeholder,
* server-side via `@corbits/folded-runs`'s `scope-routes.ts`'s
* `listTopLevelRunFires`. This filter is a client-side belt-and-suspenders
* pass against the workbench-host naming pattern alone, not a second scoping
* layer — a caller no longer needs to (and cannot) hand this a folded-run
* `./insights-api.ts`), which already excludes every non-top-level run
* (workbench host, invited agent) with no routine parent, and the
* resident never-fired deployment placeholder, server-side via
* `@corbits/run-scope`'s `scope-routes.ts`'s `listTopLevelRunFires`. This
* filter is a client-side belt-and-suspenders pass against the
* workbench-host naming pattern alone, not a second scoping layer — a
* caller no longer needs to (and cannot) hand this a non-top-level run
* id set. CL-6062 replaced the dead `/me/workflows/runs` feed (its
* `anchorRunId IS NULL` filter never matched anything, since every
* addressed run self-anchors at creation) with this scoped one.
Expand All @@ -83,7 +84,7 @@ export function purposeRunsForInsights(
* from one, honestly falling back to the definition name for a run with
* no routine/task parent — e.g. a directly launched workflow. Never
* mapped from a client-side lookup table; the route already resolved
* `routineName` server-side (`@corbits/folded-runs`'s
* `routineName` server-side (`@corbits/run-scope`'s
* `listTopLevelRunFires`).
*/
export function runDisplayName(run: InsightsRun): string {
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/shell/routine-activity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
// `listRoutineActivity`, never on where the data actually comes from.
// Filled from `./agents-api.ts`'s `listRoutineRunFires` — the `feed=fires`
// listing, the one top-level-runs view that keeps a routine's fire despite
// it being a folded run (see that function's own comment). The plain
// `listTopLevelRuns` feed looks tempting here but is wrong: its
// `notExists(folded_run)` filter drops every routine fire by construction,
// it not being a top-level run (see that function's own comment). The
// plain `listTopLevelRuns` feed looks tempting here but is wrong: its
// top-level-only filter drops every routine fire by construction,
// so a routine genuinely running would never show up in this band or count
// toward Mission Control's "Active runs" — exactly CL-6595's desync
// between the Routines page's own "Running now" pill and Mission Control's
Expand Down
9 changes: 5 additions & 4 deletions apps/web/test/bench-activity.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,11 @@ describe("useBenchActivity", () => {
},
],
// The workbench host and the invited agent never appear here: the
// hub's `/top-level-runs?feed=fires` route excludes every folded
// run that isn't a routine fire (see `@corbits/folded-runs`'s
// `scope-routes.ts`). A routine's own fire IS a folded run, so it
// must still show up here (`run_routine1`, tagged with its
// hub's `/top-level-runs?feed=fires` route excludes every
// non-top-level run that isn't a routine fire (see
// `@corbits/run-scope`'s `scope-routes.ts`). A routine's own fire
// is not a top-level run, so it must still show up here
// (`run_routine1`, tagged with its
// `routineId`) -- that is the CL-6595 fix; a directly-triggered
// deployment with no routine parent (`run_deployment1`) is not
// routine activity and must not appear.
Expand Down
2 changes: 1 addition & 1 deletion apps/web/test/insights-route.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// CL-6062: Insights' run feed reads from the tenant-scoped top-level-runs
// endpoint (packages/folded-runs/src/scope-routes.ts), not the dead
// endpoint (packages/run-scope/src/scope-routes.ts), not the dead
// `/me/workflows/runs` (every addressed run self-anchors at creation, so
// that feed's `anchorRunId IS NULL` filter never matched anything). These
// tests exercise the real fetch wiring `InsightsRoute` owns — the unit
Expand Down
11 changes: 6 additions & 5 deletions apps/web/test/routine-activity.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// CL-6595: the shell's "Running" section and Mission Control's active-run
// count both read `listRoutineActivity`, which must source the `feed=fires`
// listing — the one top-level-runs view that keeps a routine's fire (see
// `@corbits/folded-runs`'s `scope-routes.ts`). The plain `listTopLevelRuns`
// feed excludes every folded run, and a routine fire IS a folded run, so a
// routine genuinely running would never appear here at all -- Mission
// `@corbits/run-scope`'s `scope-routes.ts`). The plain `listTopLevelRuns`
// feed excludes every non-top-level run, and a routine fire is not a
// top-level run, so a routine genuinely running would never appear
// here at all -- Mission
// Control would read "0 active" while the Routines page's own "Running
// now" pill (driven by the same run's `workflow_run.status`) disagreed.

Expand Down Expand Up @@ -131,8 +132,8 @@ describe("listRoutineActivity", () => {
});

// A directly-triggered deployment run is also a `feed=fires` row (it is
// not a folded run at all), but it has no routine parent -- it must not
// be counted as routine activity.
// a top-level run), but it has no routine parent -- it must not be
// counted as routine activity.
test("drops a fires-feed row with no routine parent", async () => {
stubTopLevelRunsFetch([nonRoutineFire]);
expect(await listRoutineActivity("tnt_1")).toEqual([]);
Expand Down
Loading
Loading