Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"dev": "npm --workspace web run dev",
"build": "npm --workspace web run build",
"test": "npm --workspaces run test",
"verify:recommended-flows": "node web/scripts/verify-recommended-flow-catalog.mjs",
"verify:catalog-gates": "node web/scripts/verify-catalog-gates.mjs",
"verify:recommended-flows": "npm run verify:catalog-gates && node web/scripts/verify-recommended-flow-catalog.mjs",
"preview": "npm --workspace web run preview",
"dev:teams": "CLOUD_DEV_ORIGIN=http://127.0.0.1:3101 npm --workspace web run dev -- --hostname 127.0.0.1 --port 3100"
}
Expand Down
13 changes: 10 additions & 3 deletions web/app/flows/plugins/PluginsGallery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ export function PluginsGallery() {
<FadeIn direction="up" delay={120}>
<p className={s.subtitle}>
A curated catalog of schema-2 flow extensions. Each card pins a public GitHub
directory and an install badge that opens Cloud with the base flow and the plugin
source.
directory. Install controls appear only after every declared runtime dependency has
merge and deployment evidence.
</p>
</FadeIn>

Expand Down Expand Up @@ -106,7 +106,7 @@ export function PluginsGallery() {
const pluginUrl = flowPluginSourceUrl(plugin);
const tier = FLOW_PLUGIN_TRUST_TIER_COPY[plugin.tier];
const badgeMarkdown =
flowUrl &&
installHref && flowUrl &&
flowPluginBadgeMarkdown({
flowUrl,
plugins: [pluginUrl],
Expand All @@ -130,7 +130,14 @@ export function PluginsGallery() {
))}
<span className={s.chip}>sha {plugin.ref.slice(0, 12)}</span>
<span className={s.chip}>sha256:{plugin.digest.slice(0, 12)}</span>
<span className={s.chip}>runtime {plugin.runtime.version}</span>
</div>
{plugin.activation.state === 'blocked' ? (
<p className={s.note}>
Catalog only: activation is blocked. Required merge and deployment evidence:
{' '}{plugin.activation.dependencies.map(dependency => dependency.id).join(', ')}.
</p>
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
) : null}
{pluginHasUnroutableTriggers(plugin) ? (
<p className={s.note}>
Fail-closed: GitHub <code>pull_request.ready_for_review</code>,{' '}
Expand Down
4 changes: 2 additions & 2 deletions web/app/flows/plugins/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { SiteNav } from '../../../components/SiteNav';
import { absoluteUrl, SITE_NAME } from '../../../lib/site';
import { PluginsGallery } from './PluginsGallery';

const title = 'Flow plugins — Install onto a base flow';
const title = 'Flow plugins — Catalog and release status';
const description =
'A curated catalog of schema-2 flow extensions. Install Babysitter onto Software Garden with a pinned sha, digest, and trust tier.';
'A curated catalog of schema-2 flow extensions with pinned artifacts, runtime provenance, trust tiers, and fail-closed activation gates.';

export const metadata: Metadata = {
title,
Expand Down
40 changes: 27 additions & 13 deletions web/content/docs/relayflows/plugins.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A **flow plugin** is a directory in a public GitHub repository whose `flows-plug
{ "schema": 2, "kind": "flow-extension" }
```

The entry default-exports `flow()` and declares handlers, hooks, triggers, permissions, compat, and the same mandatory `preflight`. Browse the vendored catalog on the [plugin gallery](/flows/plugins). Each card's **Install plugin** badge opens Cloud with the base flow and the plugin source:
The entry default-exports `flow()` and declares handlers, hooks, triggers, permissions, compat, and the same mandatory `preflight`. Browse the vendored catalog on the [plugin gallery](/flows/plugins). An available card's **Install plugin** badge opens Cloud with the base flow and the plugin source:

```text
/cloud/flows/deploy?flow=<base url>&plugin=<plugin url>
Expand All @@ -18,7 +18,7 @@ The entry default-exports `flow()` and declares handlers, hooks, triggers, permi
`plugin` may repeat. The badge helper appends each one so a second plugin does not overwrite the first.

<BannerLink href="/flows/plugins" icon="rocket">
See the plugin gallery — Babysitter on Software Garden, with the install badge.
See the plugin gallery — including Babysitter's pinned artifact and release gate.
</BannerLink>

## `flows-plugin.json` schema 2
Expand Down Expand Up @@ -67,7 +67,7 @@ Rules that matter at review time:
- Manifest triggers are validated against the surface registry `providerEventTypes`. An event the registry cannot route is `plugin_event_unroutable`.

<Warning>
Relayflows 2.0.26 carries all eleven Babysitter event identities, but the authored executor still refuses a matching handler before either body starts because schema-2 permissions are not isolated there. Cloud may enable Babysitter only through the separately authorized existing-session lineage path; an arbitrary labelled pull request is not execution authority.
Relayflows SDK 2.0.31 carries the isolated hosted runtime for the reviewed Babysitter artifact, but no Cloud capability adapter or Relay native existing-session delivery release exists yet. The catalog therefore remains metadata-only and exposes no install control. Cloud may enable Babysitter only after both dependencies are merged and deployed; an arbitrary labelled pull request is not execution authority.
</Warning>

## `flows add`
Expand Down Expand Up @@ -118,20 +118,34 @@ The gallery and the deploy wizard display a tier. **The label is never used to s
| **verified** | bundle `identity.json` keyid matches a publisher key registered in Cloud |
| **community** | anything else |

Babysitter in catalog v2 is **first-party**: its `v2.0.26` commit is reachable from `AgentWorkforce/flows` main. The label does not widen runtime authority.
Babysitter in catalog v3 is **first-party**: its reviewed `v2.0.26` artifact commit is reachable from `AgentWorkforce/flows` main, and the hosted runtime provenance is the published SDK `v2.0.31` release. The label does not widen runtime authority.

<Note>
`permissions.writes` stays a reviewed declaration labelled UNENFORCED until gate 8. Displaying a first-party or verified badge does not enforce write scope, skip the digest, or route an event the registry does not carry.
</Note>

## Install badge

`flowPluginBadgeMarkdown()` renders the README form. `plugin` is appended so repeats survive:

```markdown
[![Install plugin](https://agentrelay.com/deploy-flow_small.svg)](https://agentrelay.com/cloud/flows/deploy?flow=https%3A%2F%2Fgithub.com%2FAgentWorkforce%2Fflows%2Fblob%2F8b33ebab8347514f80d9da5a81206a087f641714%2Fexamples%2Fsoftware-factory%2Fsoftware-factory.flow.ts&plugin=https%3A%2F%2Fgithub.com%2FAgentWorkforce%2Fflows%2Ftree%2F8b33ebab8347514f80d9da5a81206a087f641714%2Fextensions%2Fbabysitter)
```

The first plugin in the vendored catalog is Babysitter. Its base flow URL is Software Garden (`software-factory`); its plugin URL is the tree at the pinned sha. The [plugin gallery](/flows/plugins) shows the live badge.

The catalog itself is versioned JSON, `{version:2, plugins:[{name, description, source:{owner,repo,path}, ref, digest, manifestSha256, compat, tier, base}]}`. Any public repo with a `flows-plugin.json` is installable by URL; the catalog is a curated index, not a gate.
`flowPluginBadgeMarkdown()` renders the README form for an extension whose activation gate is ready. `plugin` is appended so repeats survive.

Babysitter's gate requires both `cloud-babysitter-capability-adapter` and `relay-native-existing-session-delivery` to carry a pull request, merge commit, merge time, deployment receipt, and deployment time. Until both proofs are recorded and the gate state is `ready`, `flowPluginInstallHref()` returns `null` and the gallery shows catalog status plus source only.

The catalog itself is versioned JSON, `{version:3, plugins:[{name, description, source:{owner,repo,path}, ref, digest, manifestSha256, compat, runtime, activation, tier, base}]}`. Any public repo with a `flows-plugin.json` remains installable by an explicit source URL; the curated catalog does not advertise an activation route until its dependency gate is satisfied.

Ready catalog entries must pass live, read-only GitHub receipt verification in CI.
The code-owned implementation contract binds `cloud-babysitter-capability-adapter`
to [Cloud PR #3989](https://github.com/AgentWorkforce/cloud/pull/3989) and
`relay-native-existing-session-delivery` to
[Relay PR #1851](https://github.com/AgentWorkforce/relay/pull/1851). Unrelated PRs
in those repositories cannot satisfy either dependency. A replacement implementation
requires a reviewed code change to this contract.
`pullRequestUrl` must identify a merged PR into the dependency repository's `main`,
with the exact `mergedCommit` and `mergedAt`. `deploymentUrl` must be the canonical
GitHub API deployment URL (`https://api.github.com/repos/OWNER/REPO/deployments/ID`).
That deployment must identify the same commit in the non-transient `production`
environment, and its latest status must be successful with `created_at` matching
`deployedAt`. Arbitrary HTTPS links, build runs, private/unavailable receipts and
unsupported deployment systems cannot make an entry ready. Blocked entries do not
require network receipts and may retain evidence without enabling installation.
The client checks the published catalog's shape; CI verifies its provenance, and
Cloud remains responsible for server-side activation authorization.
6 changes: 3 additions & 3 deletions web/content/docs/relayflows/recommended.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ Recommended flows are maintained starting points. The catalog is public, version

Software Garden is the display name of the first recommended flow. Its stable catalog and authored flow ID is `software-factory`: a GitHub issue starts implementation, deterministic repository checks, adversarial review, and a pull request for a human decision.

The released source uses Claude Code for implementation and review, so catalog version 2 allows and defaults only that harness. A future catalog version can point at a new released source with a different requirement; clients do not rewrite the authored flow.
The released source uses Claude Code for implementation and review, so catalog version 3 allows and defaults only that harness. A future catalog version can point at a new released source with a different requirement; clients do not rewrite the authored flow.

Software Garden currently supports GitHub repositories. Deploy one listener per repository using the direct-source API below. The catalog deliberately does not define Babysitter behavior. Babysitter is a [flow plugin](/docs/relayflows/plugins) installed onto Software Garden, not a recommended flow of its own.
Software Garden currently supports GitHub repositories. Deploy one listener per repository using the direct-source API below. Babysitter remains a [flow plugin](/docs/relayflows/plugins), not a recommended flow of its own. The catalog carries its immutable artifact and Relayflows SDK 2.0.31 runtime provenance as inert extension metadata; activation stays blocked until the Cloud capability adapter and Relay native delivery both carry merge and deployment evidence.

## Catalog API

Expand All @@ -22,7 +22,7 @@ GET https://agentrelay.com/api/v1/flows/catalog
GET https://agentrelay.com/api/v1/flows/catalog/software-factory
```

The list response starts with `schemaVersion: 1` and `catalogVersion: 2`. Every flow has a stable `id`, its own numeric `version`, display copy, repository-host support, trigger defaults, required/default activation inputs, and an immutable source reference.
The list response starts with `schemaVersion: 1` and `catalogVersion: 3`. Every flow has a stable `id`, its own numeric `version`, display copy, repository-host support, trigger defaults, required/default activation inputs, and an immutable source reference. Optional extension entries are metadata only unless their activation gate is `ready` and every declared dependency has merge and deployment evidence.

The catalog does not copy or generate the flow body. `source` names the canonical `AgentWorkforce/flows` owner, repository, path, release tag, full commit SHA, GitHub blob and raw URLs, media type, and SHA-256 content digest. Both URLs contain the commit SHA, never a mutable branch:

Expand Down
22 changes: 20 additions & 2 deletions web/data/flow-plugin-catalog.v1.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,32 @@
{
"version": 2,
"version": 3,
"plugins": [
{
"name": "babysitter",
"description": "Native Babysitter for Software Garden: eleven GitHub wake events request one authorized existing-session turn. Cloud rechecks the live babysit label, pull-request head, and session binding; the extension holds no GitHub write or merge authority. Handler execution remains fail-closed until the Cloud capability adapter and native delivery path ship.",
"description": "Native Babysitter for Software Garden: eleven GitHub wake events request one authorized existing-session turn. Cloud rechecks the live babysit label, pull-request head, and session binding; the extension holds no GitHub write or merge authority. This entry is catalog-only until the Cloud capability adapter and Relay native delivery are both merged and deployed.",
"source": { "owner": "AgentWorkforce", "repo": "flows", "path": "extensions/babysitter" },
"ref": "8b33ebab8347514f80d9da5a81206a087f641714",
"digest": "bdf2187b9a242667d34bbc63e7a744753e146dc8cd6f4047047f2aed28f406ee",
"manifestSha256": "5631a06bbdc8186f4ee0ff955610ead24d001c5197b59fb1fe81fe422c44f226",
"compat": { "surface": "^2.0.26", "sdk": "^2.0.26", "base": ["software-factory"] },
"runtime": { "package": "@relayflows/sdk", "version": "2.0.31", "release": "v2.0.31" },
"activation": {
"state": "blocked",
"dependencies": [
{
"id": "cloud-babysitter-capability-adapter",
"repository": "AgentWorkforce/cloud",
"requiredState": "merged-and-deployed",
"evidence": null
},
{
"id": "relay-native-existing-session-delivery",
"repository": "AgentWorkforce/relay",
"requiredState": "merged-and-deployed",
"evidence": null
}
]
},
"tier": "first-party",
"base": ["software-factory"]
}
Expand Down
33 changes: 31 additions & 2 deletions web/data/recommended-flow-catalog.v1.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"schemaVersion": 1,
"catalogVersion": 2,
"catalogVersion": 3,
"flows": [
{
"id": "software-factory",
"version": 2,
"version": 3,
"name": "Software Garden",
"summary": "Turn GitHub issues into reviewed, tested pull requests.",
"description": "Implement a ticket, run the repository checks outside the agent, put the change through adversarial review, and open a pull request for a human decision.",
Expand All @@ -21,6 +21,35 @@
},
"allowedAgents": ["claude"]
},
"extensions": [
{
"id": "babysitter",
"version": "0.2.0",
"runtime": { "package": "@relayflows/sdk", "version": "2.0.31", "release": "v2.0.31" },
"artifact": {
"ref": "github:AgentWorkforce/flows@8b33ebab8347514f80d9da5a81206a087f641714#extensions/babysitter",
Comment thread
AgentRelayBot marked this conversation as resolved.
"digest": "bdf2187b9a242667d34bbc63e7a744753e146dc8cd6f4047047f2aed28f406ee",
"manifestSha256": "5631a06bbdc8186f4ee0ff955610ead24d001c5197b59fb1fe81fe422c44f226"
},
"activation": {
"state": "blocked",
"dependencies": [
{
"id": "cloud-babysitter-capability-adapter",
"repository": "AgentWorkforce/cloud",
"requiredState": "merged-and-deployed",
"evidence": null
},
{
"id": "relay-native-existing-session-delivery",
"repository": "AgentWorkforce/relay",
"requiredState": "merged-and-deployed",
"evidence": null
}
]
}
}
],
"source": {
"kind": "github",
"owner": "AgentWorkforce",
Expand Down
Loading
Loading