Flow Kit Authoring Guide#
A Flow Kit is a portable workflow bundle you author once and install into any Flow Agents workspace. It lets you package one or more Flow Definitions — plus optional skills, docs, adapters, evals, and assets — under a single validated manifest. The same install, validation, and activation path that ships the built-in Builder Kit is available to your own kits.
This guide walks you from an empty directory to a validated, locally installed kit.
Concepts#
- Kit — a directory with a root
kit.jsonmanifest and the assets it declares. The manifest is the contract; Flow Agents validates it before anything is copied. - Flow Definition — a
.flow.jsonfile that declares steps, gates, and expected evidence. Validation of the Flow Definition semantics belongs to Kontour Flow; the kit contract delegates to it. - Activation — the step that reads the installed kit and writes runtime-local files into your workspace. Both
codex-localandstrands-localadapters activate Flow Definitions, skills, and docs. See the Activate section for the full asset-class table.
Directory layout#
my-kit/
kit.json ← required manifest
flows/
review.flow.json ← at least one Flow Definition
docs/ ← optional
README.md
All paths declared in kit.json must be relative to the kit directory and must not contain ... The kit must be fully self-contained so it can be installed from any machine or worktree.
Minimal kit.json#
{
"schema_version": "1.0",
"id": "my-kit",
"name": "My Kit",
"description": "A minimal kit that adds a review flow.",
"flows": [
{
"id": "my-kit.review",
"path": "flows/review.flow.json",
"description": "Review a change against agreed criteria."
}
]
}
Required fields:
| Field | Rule |
|---|---|
schema_version |
Must be "1.0" |
id |
Stable kebab-case string, e.g. review-kit |
name |
Non-empty display name |
flows |
Non-empty list; each entry must have id and path |
Optional fields: product_name, description, skills, docs, adapters, evals, assets, dependencies (cross-kit dependency declarations; see Cross-kit dependencies), workflow_triggers (structured workflow steering keyed by engine trigger names such as implementation-work-detected), hook_influence_expectations (kit-owned required hook-influence fixture expectations), agent_spawn_triggers (perimeter trigger surfaces that spawn agent runs plus their dedup/cooldown/cap/concurrency guard config; validation warns when a spawning surface lacks complete guards — see context/contracts/trigger-guards.md), observability_contribution (an optional host-neutral read descriptor; see Kit observability contribution contract), default_flow (the flow workflow start runs when no --flow is given; see Default flow), and first_party (legacy catalog/marketplace metadata; no runtime privilege). Optional asset fields list relative asset paths or objects with id, path, and optional description. skills and docs assets are activated by both adapters alongside flows. adapters, evals, and assets appear in diagnostics as skipped_assets (see the Activate section for the full per-adapter table).
Minimal flow file#
A Flow Definition at minimum needs id, version, steps, and gates. Steps form a linked list; each gate names the step it guards and the evidence it expects.
{
"id": "my-kit.review",
"version": "1.0",
"steps": [
{ "id": "review", "next": "done" },
{ "id": "done", "next": null }
],
"gates": {
"review-gate": {
"step": "review",
"expects": [
{
"id": "review-finding",
"kind": "trust.bundle",
"required": true,
"description": "The change was reviewed and findings were recorded.",
"bundle_claim": {
"claimType": "my-kit.review.finding",
"subjectType": "artifact",
"accepted_statuses": ["trusted", "accepted"]
}
}
]
}
}
}
The id in the flow file should match the id declared in kit.json's flows list. Look at kits/builder/flows/shape.flow.json and kits/builder/flows/build.flow.json in this repository for fuller examples of multi-step flows with required and optional gate evidence.
Flow Definitions may compose another declared Flow Definition at a step with uses_flow. The parent keeps lifecycle ownership (active_flow_id can remain the parent flow), while gate resolution for that step comes from the child flow with the same step id. Use this scalar form for one reusable extension such as publish, CI merge readiness, or learning closeout:
{
"id": "builder.build",
"steps": [
{ "id": "verify", "next": "pr-open" },
{ "id": "pr-open", "next": "merge-ready-ci", "uses_flow": "builder.publish-learn" },
{ "id": "merge-ready-ci", "next": "learn", "uses_flow": "builder.publish-learn" },
{ "id": "learn", "next": "done", "uses_flow": "builder.publish-learn" }
]
}
The additive uses_flows form accepts an ordered list of required children at one extension step. Each child must declare exactly one gate for that same step and export every expectation it contributes. The resolver preflights all children, then emits one deterministic flow-agents.aggregate.<step-id> gate containing every imported expectation in declared order. It records each child gate in flow_agents_contributions provenance. All required expectations participate in that one parent gate; a missing, failed, disputed, stale, or not_verified child claim prevents verification.
{
"id": "my-kit.release",
"steps": [
{
"id": "verify",
"next": null,
"uses_flows": ["verification.verify", "veritas.verify", "third-party.verify"]
}
]
}
Do not declare both uses_flow and uses_flows on one step, do not repeat a child flow id, and do not place a parent-owned gate on a composed step; each shape is rejected. The aggregate gate id is reserved: a collision is rejected rather than overwritten. Child route-back declarations merge only when every declared retry policy is identical and a reason maps to one target; conflicting targets, retry limits, or malformed/partial metadata are rejected. Scalar uses_flow remains supported unchanged.
This is a composition primitive only. It neither chooses installed child kits nor reads per-Kit configuration: #579 owns selected/optional dependency closure and #275 owns committed effective configuration and activation semantics. Until those contracts select contributions, an author must provide the explicit child list and treat optional-absence and configuration-precedence behavior as NOT_VERIFIED here.
An optional named terminal sentinel may make the source definition easier to
read, for example { "id": "shape-done", "next": null }. When that sentinel is
referenced by another step and has no gate, effective-definition compilation
removes it and sets its predecessor's next to null, which is Flow's native
completion edge. The sentinel name is not significant.
Validate#
Before installing or sharing a kit, run validation from the flow-agents checkout:
npm run validate:source -- --kit path/to/my-kit
This runs the same repository contract validation used by install-local. A validation failure exits nonzero with a diagnostic. Fix errors and re-run until it passes cleanly.
The full source-tree validation (no --kit flag) validates every kit listed by the built-in catalog. An unreadable or empty catalog, or an entry without a path, fails validation:
npm run validate:source --
Install locally#
Once validation passes, install the kit into a target workspace:
npx @kontourai/flow-agents kit install path/to/my-kit --dest /path/to/workspace
--dest is the installed Flow Agents bundle root. When omitted the command uses the current directory. From a contributor checkout of this repository, the equivalent form is npm run flow-kit -- <command>.
Confirm the install:
npx @kontourai/flow-agents kit list --dest /path/to/workspace
npx @kontourai/flow-agents kit status my-kit --dest /path/to/workspace
list prints one summary line per installed kit. status prints JSON provenance including the SHA256 content hash and installed or missing state.
To replace an existing install after you update the kit source:
npx @kontourai/flow-agents kit install path/to/my-kit --dest /path/to/workspace --update
Activate#
After installing, run activate to write runtime-local files into the workspace:
npx @kontourai/flow-agents kit activate --dest /path/to/workspace --format json
The codex-local adapter is selected automatically. To activate for Strands, pass --adapter strands-local.
What each adapter activates#
Each adapter copies declared assets into .kontourai/flow-agents/projections/<adapter>/ and produces an activation.json manifest. The table below shows which asset classes are activated today:
| Asset class | codex-local |
strands-local |
Notes |
|---|---|---|---|
flows |
Activated — .kontourai/flow-agents/projections/codex/flows/<kit-id>/<asset-id>.flow.json |
Activated — .kontourai/flow-agents/projections/strands/flows/<kit-id>/<asset-id>.flow.json |
Gate definitions read by each adapter's flow-routing layer. |
skills |
Activated — .kontourai/flow-agents/projections/codex/skills/<kit-id>/<filename> |
Activated — .kontourai/flow-agents/projections/strands/skills/<kit-id>/<filename> |
Agent guidance markdown. For codex-local, reference these paths from AGENTS.md. For strands-local, the Strands steering layer can glob for *.md under skills/ during system-prompt injection. |
docs |
Activated — .kontourai/flow-agents/projections/codex/docs/<kit-id>/<filename> |
Activated — .kontourai/flow-agents/projections/strands/docs/<kit-id>/<filename> |
Documentation assets. Co-located with skill files for easy reference. |
adapters |
skipped_assets |
skipped_assets |
Framework or runtime adapter code — not copied by the activation layer. |
evals |
skipped_assets |
skipped_assets |
Evaluation suites — not run or copied during activation. |
assets |
skipped_assets |
skipped_assets |
General supporting assets — not copied during activation. |
Assets in skipped_assets are recorded in activation.json for diagnostics but are not an error. They are not activated because no activation path is defined for those classes in the current adapters.
Host hook files use the separate provisions path. A provision with explicit
host and Conduit kind is installed through that host's Conduit adapter by
flow-agents kit provision or by flow-agents init --activate-kit; it is not
an active runtime projection merely because kit activate copied flows and
skills. Use merge: "hooks-json" only for a reviewed hooks configuration. The
Conduit receipt proves the installed bytes, while the host's own trust and
execution checks remain separate. See the Flow Kit Repository Contract.
Flows with a missing id field in kit.json are also placed in skipped_assets with an explicit reason.
When installing through npx @kontourai/flow-agents init with the Codex runtime, pass --activate-kits to run activation as part of init:
npx @kontourai/flow-agents init --runtime codex --dest /path/to/workspace --activate-kits --yes
init activates no kits by default. To activate one or more catalog kits explicitly, pass --activate-kit <kit-id> once per selected kit. Declared kit dependencies are auto-included transitively during activation; for example, activating Builder also activates its Knowledge dependency:
npx @kontourai/flow-agents init --runtime codex --dest /path/to/workspace --activate-kit builder --yes
--activate-kits remains a backwards-compatible alias for selecting every catalog kit.
Troubleshooting#
Common validation errors and fixes are documented in the Flow Kit Repository Contract. The most frequent:
kit.json: .schema_version must be "1.0"— update the manifest.kit.json: .id must be a stable kebab-case string— use a lowercase id likereview-kit.kit.json: .flows must be a non-empty list— declare at least one Flow Definition.kit.json: flows[0].path points at missing Flow Definition— add the file or fix the path.kit.json: docs[0].path points at missing asset— add the asset or remove the entry.
For path errors: all declared paths must be relative, must not contain .., and must point at existing files. Absolute paths are rejected because a kit must be portable between machines.
For conflicts on re-install: if you install a different source with an existing kit id, the command fails unless you pass --update. Use --force to re-copy an existing same-source install after validation.
For cross-kit dependency errors:
kit.json: dependencies[N].kit_id must be a kebab-case kit id— the entry'skit_idis missing or not lowercase kebab-case. Fix the id.kit.json: dependencies[N].kit_id must not reference the declaring kit itself— remove the self-referential entry; a kit cannot depend on itself.kit.json: dependencies[N].kit_id duplicates '<id>'— collapse the duplicate declaration to a single entry.warning: kit '<id>' declares a dependency on '<dep>' ... which is not installed(at install) — advisory only; install the depended-on kit withflow-agents kit install <source>before activating, or activation will fail.<id>: declares a dependency on kit '<dep>' ... which is not installed or activated(at activate, non-zero exit) — install the missing kit and re-activate, or remove the dependency declaration if it is no longer needed.
See the Flow Kit Repository Contract for the full validation rules, registry schema, activation diagnostics, and the install/update/force semantics.
Layering: container vs. agent extension#
A Flow Agents Kit is built on two distinct layers. Understanding the split helps you know which rules come from Flow and which come from Flow Agents.
Layer 1: the Flow Kit container (Flow-owned)#
The container contract is owned by Kontour Flow. It governs:
kit.jsonrequired fields:schema_version("1.0"),id(kebab-case),name,flows(non-empty list withpathentries).- Optional core fields:
description,product_name. - Path rules: all declared paths must be relative, must not contain
.., and must resolve inside the kit directory. - The extension model: unknown top-level fields are consumer extensions; core validation ignores-but-permits them.
Container validation is surfaced in Flow's CLI as flow kit validate <kit-dir>. Flow Agents delegates core container validation to @kontourai/flow's validateKitContainer library function; the contract lives once, in Flow.
For the authoritative container spec and JSON Schema, see kontourai/flow#67 (the spec PR) and the published schemas/flow-kit-container.schema.json in the @kontourai/flow package.
Layer 2: the Flow Agents agent extension (Flow Agents-owned)#
The agent extension is owned by Flow Agents. It defines the optional asset classes that turn a Flow Kit into a Flow Agents Kit:
| Extension field | Asset type |
|---|---|
skills |
Reusable agent skill procedures |
docs |
Documentation assets |
adapters |
Runtime or framework adapters |
evals |
Evaluation suites |
assets |
General supporting assets |
Each extension field is an optional array of entries with id, path, and optional description. Extension fields are validated by Flow Agents using the same path rules as the container layer (relative, no .., must exist). Unknown extension entries are recorded as skipped_assets during activation rather than treated as errors.
Cross-kit dependencies#
A kit may declare that it depends on another kit whose skills it invokes at runtime. This is a Flow Agents extension-layer concern (a skill in one kit calling a skill in another), not part of the Flow-owned container contract — see ADR 0019 for the ownership rationale (grounded in the container schema's additionalProperties: true and ADR 0008's Dividing Test). It is not a package manager: it declares and validates presence, it does not fetch kits or resolve versions.
Shape:
{
"schema_version": "1.0",
"id": "builder",
"name": "Builder Kit",
"flows": [ /* ... */ ],
"dependencies": [
{
"kit_id": "knowledge",
"reason": "learning-review invokes knowledge-capture for durable knowledge storage"
}
],
"skills": [ /* ... */ ]
}
| Field | Rule |
|---|---|
kit_id |
Required. Kebab-case kit id (^[a-z][a-z0-9-]*$) of the depended-on kit. Must not reference the declaring kit itself, and must not be duplicated across entries. |
reason |
Optional string explaining why the dependency exists (which skill invokes which). |
Where it is checked:
- Shape — at
flow-agents kit install,inspect, andvalidatetime. A malformed entry (badkit_id, self-reference, duplicate) is a hard error. - Presence at install —
flow-agents kit installprints a non-blocking warning when a declared dependency is not present in the destination's local registry, then exits 0. This check sees only the local installed-kits registry, not the built-in Kit Catalog (an accepted v1 limitation). - Presence at activation —
flow-agents kit activateis a hard error (non-zero exit) when a declaredkit_idis not present among the union of built-in catalog kits and locally-installed kits.
dependencies is metadata, not evaluable-gate content, so it does not affect K0/K1/K2 conformance scoring (see the K-levels section below).
Structured workflow triggers#
A kit may declare workflow_triggers to let the engine route matching prompts into a kit workflow. Triggers do not contain freeform prose. The engine owns the rendered wording and applies the same template to every kit. Every trigger steering field is an identifier and must match ^[a-z0-9]+(?:[.-][a-z0-9]+)*$; malformed values fail closed and the trigger is skipped.
Shape:
{
"workflow_triggers": [
{
"id": "builder-build-work",
"when": "implementation-work-detected",
"target_flow_id": "builder.build",
"default_skill": "deliver",
"conditional_skills": [
{ "when": "user-requested-tdd", "skill": "tdd-workflow" }
],
"required_sequence": ["plan-work", "execute-plan", "review-work", "verify-work"],
"post_verify_targets": ["release-readiness", "learning-review"]
}
]
}
| Field | Rule |
|---|---|
id |
Required trigger id unique within the kit. |
when |
Required engine trigger category such as implementation-work-detected or knowledge-capture-detected. |
target_flow_id |
Optional flow id the session should stay on. |
default_skill |
Optional skill id to activate when no conditional skill applies. |
conditional_skills |
Optional list of { "when": "...", "skill": "..." } identifier entries. |
required_sequence |
Optional ordered list of workflow skills or steps the engine should name as the required sequence. |
post_verify_targets |
Optional list of post-verification targets such as release readiness or learning capture. |
The retired hint field is invalid. display_name is not a workflow trigger field; keep human-readable names in catalog/listing metadata such as top-level name or product_name. Do not put natural-language steering instructions in kit metadata; express routing needs through the structured identifier fields above.
A manifest alone is not discoverable — declare it in a registry too#
workflow_triggers are read by workflowTriggersFor() (scripts/hooks/lib/kit-catalog.js), which enumerates kits through readKitManifests(root). That function finds a kit.json only through one of two registries under the repository root:
kits/catalog.json— a{ "schema_version": "1.0", "kits": [{ "id", "name", "path", "description" }] }list whosepathpoints at the kit directory (kits/<kit-id>); orkits/local/installed-kits.json— the local install registry written byflow-agents kit install, which reads copies underkits/local/repositories/<kit-id>/.
A kits/<kit-id>/kit.json with no entry in either registry is invisible. Nothing reads it, nothing warns about it, and the steering hook renders an empty string — indistinguishable from a repository that declares no triggers at all. This is the failure mode to check first when configured triggers produce no steering: confirm the registry entry exists, not just the manifest.
Which registry to use:
- Committing durable, repo-owned routing policy (the common case for a product repository that wants its own delivery routing): add
kits/catalog.jsonandkits/<kit-id>/kit.json, and commit both. Both files are required. - Installing a kit as runtime overlay state: use
flow-agents kit install, which ownskits/local/**. Install state is regenerable and is not the place for committed policy.
A repository-root kit that declares workflow_triggers without a flows list is valid for routing purposes: Flow Definitions resolve through the installed package's packaged-flow fallback (src/lib/flow-resolver.ts) when the repository does not vendor its own under kits/<kit-id>/flows/. Vendor the flow files only when the repository needs to pin them.
Note that the hook resolves the repository root through git's shared common-dir root, so a manifest added on a branch in a linked worktree does not take effect for sessions elsewhere until it reaches the branch the primary checkout has open.
Default flow#
workflow start without --flow, a provider pickup's emitted start command, and the library's
startBuilderFlowSession without a flowId start the flow a kit declares as default_flow:
{
"id": "builder",
"flows": [{ "id": "builder.build", "path": "flows/build.flow.json" }],
"default_flow": "builder.build"
}
A library session already bound to a canonical run keeps its persisted flow when flowId is
omitted. The default applies when neither the caller nor that session names a flow.
The value must name a flow of the same kit that the kit lists in its own flows[]; validation
refuses anything else. The engine names no default of its own, and it resolves the declaration
fail-closed:
- Kits in the executing package are consulted first, then the project's kits. The first of those
roots holding any
default_flowdecides, so a project kit can supply a default where the package declares none but cannot replace a packaged default. - No declaration, a malformed declaration, an unreadable kit manifest or source tree, or more
than one kit declaring a default at the deciding root is refused with a message naming the
affected source; pass
--flowinstead. An absent tree differs from an unreadable existing one: an unreadable packaged tree cannot silently transfer default selection to the project. - The declared flow must pass the same admission contract as an explicit
--flow, including resolver-compatible identifiers and a canonical run (its kit binds a producer for every gate expectation); otherwise selection refuses before pickup or session artifacts are written.
A provider pickup additionally refuses a default flow that declares no selected-work
expectation, because it starts the picked-up provider Work Item.
When a kit "is" a Flow Agents Kit#
A kit is a Flow Agents Kit when it satisfies both layers:
- It passes Flow Kit container validation (valid
kit.jsonwith core fields and at least oneflowsentry). - It optionally declares one or more Flow Agents extension fields (
skills,docs,adapters,evals,assets).
A kit with only core fields (no extension fields) is a valid Flow Kit and is also a valid Flow Agents Kit — it just installs and activates only its Flow Definitions.
Why two layers?#
The split keeps ownership clean:
- Flow authors, installs, and validates the container shape. Any tool that understands Flow Kits can install any kit without knowing about Flow Agents.
- Flow Agents extends the container for agent-specific assets without modifying the core contract. Third-party kit authors who don't need skills or adapters never have to know about the extension layer.
K-levels: kit conformance and consumer-target badges#
Every Flow Agents Kit declares assets in a manifest. The K-level system classifies what consumers can do with a kit based on observable asset classes — no extra declaration needed for the level itself. Levels derive from what is present.
Conformance levels#
| Level | What is present | Who can consume it |
|---|---|---|
| K0 | Valid core Flow Kit container: schema_version, id, name, flows (non-empty). |
Any Flow consumer: gates and definition-of-done are evaluable agentlessly in CI or without an agent framework. |
| K1 | K0 + at least one Flow Agents extension field present (skills, docs, adapters, evals, or assets). |
Flow Agents (>= installed version) can activate the kit in at least one agent harness or framework. |
| K2 | K1 + evals present with at least one entry. |
Live evidence layer: eval suites run against an adapter and produce verifiable output records. |
Every kit published by Kontour is K0 or higher. K0 is the minimum bar — a kit that fails K0 is not distributable.
The degradation invariant#
Every Flow Agents Kit must remain a valid core Flow Kit container when agent-extension fields are ignored. This is the degradation invariant:
- Strip
skills,docs,adapters,evals, andassetsfrom a kit'skit.json. - The remaining manifest must satisfy the Flow Kit container contract (
schema_version,id,name,flowsnon-empty, no..traversal). - This invariant is enforced by the kit validator (
npm run validate:source -- --kit <dir>).
Why this matters: any Flow consumer (CI gate runner, definition-of-done checker, release audit tool) can evaluate a kit's gates without knowing about Flow Agents. The kit's flow definitions carry the definition-of-done independently of whether an agent ever runs.
Consumer-target derivation#
Consumer targets are derived from observable asset classes — no declaration is required for standard targets:
| Observable state | Derived target |
|---|---|
| K0 (flows present) | flow — any Flow consumer (gate evaluation, definition-of-done) |
| K1 (agent extension assets present) | flow-agents — Flow Agents activates the kit |
| Unknown top-level key(s) | Listed verbatim as third-party consumer target(s) |
Unknown top-level keys are permitted by the container spec's additionalProperties: true rule. A third-party tool built on Flow can extend a kit with its own namespace (e.g. "my-platform.widgets": [...]) — the key becomes a derived consumer-target badge without requiring any pre-registration.
Version constraints (e.g. minimum flow-agents version) are the only case where a declaration is needed beyond what derivation can reach.
Marketplace listing format: Works with: Flow (gates-only) | Flow Agents | <Consumer X>
Evidence layering: Surface and Veritas#
Kit gates reference evidence using "kind": "trust.bundle" with a bundle_claim selector (claimType, optional subjectType, accepted_statuses). This is Flow-native vocabulary in the Hachure open trust-bundle format: Flow is built on Surface, so trust bundles are the expected evidence substrate at the Flow level, validated against Hachure's trust-bundle.schema.json. They are not a Flow Agents coupling. (Earlier Flow releases used kind: "surface.claim" with a claim selector; Flow 1.3.0 replaced that with trust.bundle, kontourai/flow#84.)
Veritas is an optional claim family — a developer-repo specialization for evidence that has been through a trust pipeline. Kits may be opinionated about requiring Veritas-class evidence. Builder Kit requiring Veritas-class evidence is the kit's own policy choice, defined by Kontour as the kit author, not a platform requirement. Other kits may not require Veritas at all.
Layering summary:
- Surface = claim substrate (Flow-level, always available)
- Veritas = optional claim kind, kit-opinionated (Builder Kit requires it; others need not)
Inspecting a kit's K-level#
Use the inspect subcommand to derive a kit's conformance level and consumer targets:
npm run kit -- inspect path/to/my-kit
Output is stable JSON:
{
"kit_id": "my-kit",
"kit_name": "My Kit",
"conformance": {
"k0": true,
"k1": true,
"k2": false
},
"targets": ["flow", "flow-agents"],
"third_party_extensions": [],
"trust": "unverified"
}
Exit code 0 when the kit is at least K0 (valid core container); exit code 1 when K0 validation fails.
The inspect command is read-only and safe to run before install.
Trust axis: who vouches for a kit#
The trust axis is a separate, orthogonal classification from the K-level capability axis. It answers the question "who vouches for this kit?" rather than "what does this kit contain?".
Two orthogonal axes#
Every kit carries two independent badges:
| Axis | Values | Question answered |
|---|---|---|
| Capability (K-level) | K0 / K1 / K2 | What does the kit CONTAIN? (derived from assets) |
| Trust | verified / unverified | WHO vouches for it? |
A K2 kit can be unverified. The levels are independent.
Marketplace listing format: Works with: Flow (gates-only) | K1 | Official
official / first_party is catalog and marketplace metadata only. It grants no runtime privilege: every kit uses the same structured steering mechanism, and no capability decision keys off kit id or load provenance.
Trust levels#
| Level | Meaning | How it is assigned (v1) |
|---|---|---|
verified |
Reserved for a future third-party verification process. | Not yet implemented; the value is reserved but not granted to any kit today. |
unverified |
Default for all kits. | All current kits, including built-ins and third-party community kits. |
unverified says nothing about the quality of a kit — it only means Kontour has not vouched for it through one of the above channels.
Deferred: verified trust and cryptographic attestation (v2)#
The verified value is reserved for a future verification process. The intended v2 path:
- Third-party kit authors can apply for
verifiedstatus. - Verification evidence: the kit passes the conformance kit self-certification + a cryptographic signature or Veritas attestation.
- The conformance kit and Veritas claims are the natural substrate for this attestation layer.
- The signature or attestation would be checked by
flow-agents kit inspectat derivation time.
v1 deliberately omits the signing/attestation mechanism and the verification process. The verified value is reserved so consuming tools can handle it when it arrives without a breaking schema change.
Inspecting trust#
The trust field appears in flow-agents kit inspect output alongside conformance:
npm run kit -- inspect kits/builder
{
"kit_id": "builder",
"kit_name": "Builder Kit",
"conformance": {
"k0": true,
"k1": true,
"k2": false
},
"targets": ["flow", "flow-agents"],
"third_party_extensions": [],
"trust": "unverified"
}
A third-party kit inspected before verification:
{
"kit_id": "my-custom-kit",
"kit_name": "My Custom Kit",
"conformance": {
"k0": true,
"k1": true,
"k2": false
},
"targets": ["flow", "flow-agents"],
"third_party_extensions": [],
"trust": "unverified"
}
Direction#
Flow Kits are shareable workflow units authored once and carried across teams and workspaces.
flow-agents kit install accepts local paths and Git URLs today. Git repositories are shallow-
cloned, validated at their root, provenance-recorded, and copied without executing repository
scripts. Put kit.json at the repository root and pin a branch, tag, or SHA with #ref or
--ref.
Migration: flow-kit → flow-agents kit#
The standalone flow-kit binary was removed in this release. The flow-agents kit subcommand is the replacement.
| Old command | New command |
|---|---|
flow-kit install-local <path> |
flow-agents kit install <path> |
flow-kit install-git <url> |
flow-agents kit install <url> |
flow-kit activate |
flow-agents kit activate |
flow-kit inspect <dir> |
flow-agents kit inspect <dir> |
flow-kit list |
flow-agents kit list |
flow-kit status <id> |
flow-agents kit status <id> |
npx @kontourai/flow-agents flow-kit ... |
npx @kontourai/flow-agents kit ... |
npm run flow-kit -- ... |
npm run kit -- ... |
install-local and install-git are unified into a single install command. The source argument auto-detects whether it is a local path or a git URL (http://, https://, git+, ssh://, file://).
Running the old flow-kit command will produce a "command not found" error from your shell — there is no alias or shim. Update any scripts or CI configurations that call flow-kit to use flow-agents kit.
Portable workspace selection#
Workspace Kits v1 currently requires POSIX no-follow directory and mode semantics; Windows refuses with unsupported rather than weakening those checks. Its machine-independent files provide an inert, explicit selection for plain directories, including directories without Git. It does not activate Kits or bind running workflows. The workspace contract defines its supported fields, identity scheme, refusal behavior and proof limits.
Create .flow-agents/workspace.kits.json in an existing scope:
{
"schema_version": "1.0",
"selected": ["example-kit"],
"sources": {"example-kit": {"kind": "local", "alias": "example-source"}},
"options": {},
"provider_bindings": {},
"contributions": "all"
}
Keep acquisition locations in a separate local JSON file such as {"example-source":"/absolute/path/to/example-kit"}. Create an existing cache directory outside the scope and source directories, then run:
flow-agents kit workspace resolve --scope /absolute/workspace --cache /absolute/kit-cache --bindings /absolute/local-bindings.json
flow-agents kit workspace inspect --scope /absolute/workspace --cache /absolute/kit-cache
Commit the declaration and generated .flow-agents/workspace.kits.lock.json when appropriate. The lock contains artifact identities and required dependency edges, without machine paths or acquisition timestamps. Declare and bind every required dependency; v1 refuses optional dependencies, version ranges, nonempty options or provider bindings. Additional unselected sources are not read.
A matching lock can resolve offline from verified cached bytes without --bindings. Use --update explicitly to select changed source bytes. Inspect reports the prior identity when the declaration is stale, never fetches sources and never writes. Both commands emit JSON; verified exits 0 and all refusal outcomes exit 2. Library callers use the same implementation through @kontourai/flow-agents/workspace-kits.
Artifacts publish before the lock and are never repaired or overwritten in place. Failure before lock replacement preserves the old lock; complete unreferenced entries can remain after interruption. A cleanup failure after replacement returns recovery-required with the newly published lock identity. Existing operation markers report busy and require deliberate recovery by the owner; v1 has no automatic lock reclamation or cache cleanup. Verification establishes supported manifest/closure checks and exact cached bytes, not publisher trust, coherent source capture, workflow readiness or power-loss durability. Active runs and the legacy install/activation paths are unchanged.
Review kit-owned pending actions#
Use flow-agents kit review <kit-id> --dest <installed-root> --request <private-review-request.json>
for a kit's declared Survey review producer. This shares the native host interface
across AI-DLC and governance kits while preserving their domain decisions. See
the review producer contract
for request shape, host authority and stale-source rejection. No kit-specific
binary is required to present and apply this review.
The producer can supply optional Survey ReviewQueuePresentation hints for a
clear review title, reason for waiting, artifact acknowledgments and named decision
actions. Hints are display-only and stay separate from the original queue binding
and producer admission. Submitting a review records the producer result; kits own
the subsequent execution handoff.