@kontourai/flow-agents 3.4.3 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +4 -0
- package/CHANGELOG.md +15 -0
- package/build/src/builder-flow-run-adapter.d.ts +10 -1
- package/build/src/builder-flow-run-adapter.js +29 -1
- package/build/src/builder-flow-runtime.d.ts +18 -0
- package/build/src/builder-flow-runtime.js +205 -13
- package/build/src/builder-lifecycle-authority.d.ts +35 -0
- package/build/src/builder-lifecycle-authority.js +219 -0
- package/build/src/cli/assignment-provider.d.ts +13 -0
- package/build/src/cli/assignment-provider.js +120 -62
- package/build/src/cli/builder-run.js +46 -5
- package/build/src/cli/workflow-artifact-cleanup-audit.js +3 -0
- package/build/src/cli/workflow-sidecar.d.ts +3 -0
- package/build/src/cli/workflow-sidecar.js +140 -30
- package/build/src/cli/workflow.d.ts +2 -0
- package/build/src/cli/workflow.js +521 -0
- package/build/src/cli.js +2 -0
- package/build/src/index.d.ts +4 -0
- package/build/src/index.js +2 -0
- package/build/src/lib/flow-resolver.js +7 -2
- package/build/src/lib/package-version.d.ts +2 -0
- package/build/src/lib/package-version.js +13 -0
- package/build/src/lib/pinned-cli-command.d.ts +6 -0
- package/build/src/lib/pinned-cli-command.js +21 -0
- package/context/contracts/artifact-contract.md +1 -1
- package/context/contracts/assignment-provider-contract.md +5 -2
- package/context/scripts/hooks/config-protection.js +8 -1
- package/context/scripts/hooks/lib/config-protection-remedies.js +3 -0
- package/context/scripts/hooks/stop-goal-fit.js +1 -1
- package/docs/context-map.md +2 -0
- package/docs/public-workflow-cli.md +63 -0
- package/docs/spec/builder-flow-runtime.md +49 -5
- package/docs/workflow-usage-guide.md +5 -0
- package/evals/ci/run-baseline.sh +2 -0
- package/evals/integration/test_assignment_provider_local_file.sh +54 -0
- package/evals/integration/test_builder_entry_enforcement.sh +241 -24
- package/evals/integration/test_bundle_install.sh +97 -0
- package/evals/integration/test_current_json_per_actor.sh +1 -0
- package/evals/integration/test_dual_emit_flow_step.sh +2 -0
- package/evals/integration/test_flowdef_session_activation.sh +6 -3
- package/evals/integration/test_goal_fit_escape_hatch.sh +3 -3
- package/evals/integration/test_phase_map_and_gate_claim.sh +4 -0
- package/evals/integration/test_public_workflow_cli.sh +259 -0
- package/evals/integration/test_workflow_sidecar_writer.sh +1 -0
- package/package.json +2 -2
- package/schemas/builder-lifecycle-authorization.schema.json +57 -0
- package/schemas/lifecycle-authority-keys.schema.json +25 -0
- package/schemas/workflow-state.schema.json +1 -1
- package/scripts/hooks/config-protection.js +8 -1
- package/scripts/hooks/lib/config-protection-remedies.js +3 -0
- package/scripts/hooks/stop-goal-fit.js +1 -1
- package/src/builder-flow-run-adapter.ts +47 -0
- package/src/builder-flow-runtime.ts +216 -4
- package/src/builder-lifecycle-authority.ts +218 -0
- package/src/cli/assignment-provider.ts +84 -20
- package/src/cli/builder-flow-runtime.test.mjs +404 -1
- package/src/cli/builder-run.ts +56 -5
- package/src/cli/workflow-artifact-cleanup-audit.ts +3 -0
- package/src/cli/workflow-sidecar.ts +138 -31
- package/src/cli/workflow.ts +471 -0
- package/src/cli.ts +2 -0
- package/src/index.ts +14 -0
- package/src/lib/flow-resolver.ts +6 -2
- package/src/lib/package-version.ts +15 -0
- package/src/lib/pinned-cli-command.ts +23 -0
|
@@ -138,8 +138,10 @@ detect an incompatible future shape before parsing fields it does not understand
|
|
|
138
138
|
{
|
|
139
139
|
"schema_version": "1.0",
|
|
140
140
|
"role": "AssignmentClaimRecord",
|
|
141
|
-
"subject_id": "kontourai
|
|
141
|
+
"subject_id": "kontourai-flow-agents-290",
|
|
142
142
|
"actor": { "runtime": "claude-code", "session_id": "...", "host": "...", "human": null },
|
|
143
|
+
"actor_key": "claude-code:...:host",
|
|
144
|
+
"work_item_ref": "kontourai/flow-agents#290",
|
|
143
145
|
"claimed_at": "2026-07-02T00:00:00Z",
|
|
144
146
|
"ttl_seconds": 1800,
|
|
145
147
|
"branch": "agent/<actor>/<slug>",
|
|
@@ -152,9 +154,10 @@ detect an incompatible future shape before parsing fields it does not understand
|
|
|
152
154
|
| --- | --- | --- |
|
|
153
155
|
| `schema_version` | yes | Version of this record shape, `"1.0"`. |
|
|
154
156
|
| `role` | yes | Constant `"AssignmentClaimRecord"`, for readers scanning mixed content (e.g. a GitHub comment thread) for this record type. |
|
|
155
|
-
| `subject_id` | yes | The
|
|
157
|
+
| `subject_id` | yes | The provider subject key. The local-file provider uses the deterministic session slug; provider-backed records may use their native subject identifier. |
|
|
156
158
|
| `actor` | yes | `{ runtime, session_id, host, human? }` — the exact struct `actor-identity.js` defines. `human` is set (non-null) only for a human assignee; its presence, not a username heuristic, gates the human-held join state. |
|
|
157
159
|
| `actor_key` | no (additive, #291) | The canonical `resolveActor(env).actor` string for the claiming actor — the same flat/bare token `liveness whoami`, `liveness claim --actor`, per-actor `current.json`, and pull-work's `--self-actor` all use. When present, `computeEffectiveState` compares against THIS (not a re-serialization of `actor`) for both self-recognition and the liveness join, because `serializeActor(actor)` and `resolveActor(env).actor` diverge for an explicit-override actor (a bare token vs. a `explicit-override:<value>:<host>` triple) while agreeing for a derived actor. Absent on any pre-#291 record or fixture — `computeEffectiveState` falls back to `serializeActor(actor)` in that case, reproducing pre-#291 behavior exactly. |
|
|
160
|
+
| `work_item_ref` | no (additive, #541) | Exact Work Item reference acquired by Builder `ensure-session`. This preserves identity beyond the local provider's lossy filesystem slug and allows an interrupted acquisition to retry safely. Older records and ordinary assignment-provider claims omit it and cannot automatically satisfy `builder.pull-work.selected`. |
|
|
158
161
|
| `claimed_at` | yes | ISO-8601 timestamp the claim was recorded. Mirrors the liveness stream's own claim-event field so a reader compares freshness with one mental model across both layers, even though the two are stored in different media. |
|
|
159
162
|
| `ttl_seconds` | yes | Same field name/semantics as the liveness stream's `ttlSeconds` (default `1800`). |
|
|
160
163
|
| `branch` | yes | The branch this actor is working on, per the `agent/<actor>/<slug>` convention. |
|
|
@@ -120,6 +120,13 @@ function checkProtectedPathPattern(filePath) {
|
|
|
120
120
|
};
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
if (/(?:^|\/)\.flow-agents\/lifecycle-authority-keys\.json$/.test(norm)) {
|
|
124
|
+
return {
|
|
125
|
+
name: '.flow-agents/lifecycle-authority-keys.json',
|
|
126
|
+
reason: 'an agent could replace the pinned lifecycle authority key and forge cancellation authority',
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
123
130
|
// .kontourai/flow-agents/current.json — an agent could forge active_flow_id / active_step_id
|
|
124
131
|
// to route the gate to a permissive or empty-expects FlowDefinition.
|
|
125
132
|
// SAFE: the workflow CLI writes current.json via fs (writeJson → fs.writeFileSync),
|
|
@@ -426,7 +433,7 @@ function checkCommandForBypass(command) {
|
|
|
426
433
|
*/
|
|
427
434
|
// #379: the delivery/ arms carry an optional (?:[^/]+\/)? segment so redirects/tee to the
|
|
428
435
|
// per-session path delivery/<slug>/trust.bundle (+ checkpoint) are caught, not just the flat path.
|
|
429
|
-
const REDIRECT_PROTECTED_RE = /(?:^|\/|~\/)(\.bash_profile|\.bashrc|\.profile|\.zprofile|\.zshrc)$|(?:^|\/)\.claude\/settings(?:\.local)?\.json$|(?:^|\/)(?:\.kontourai\/flow-agents|\.flow-agents)\/current\.json$|(?:^|\/)(?:\.kontourai\/flow-agents|\.flow-agents)\/current\/[^/]+\.json$|(?:^|\/)(?:\.kontourai\/flow-agents|\.flow-agents)\/\.goal-fit-block-streak\.json$|(?:^|\/)(?:\.kontourai\/flow-agents|\.flow-agents)\/[^/]+\/state\.json$|(?:^|\/)(?:\.kontourai\/flow-agents|\.flow-agents)\/[^/]+\/trust\.bundle$|(?:^|\/)delivery\/(?:[^/]+\/)?trust\.bundle$|(?:^|\/)delivery\/(?:[^/]+\/)?trust\.checkpoint\.json$/;
|
|
436
|
+
const REDIRECT_PROTECTED_RE = /(?:^|\/|~\/)(\.bash_profile|\.bashrc|\.profile|\.zprofile|\.zshrc)$|(?:^|\/)\.claude\/settings(?:\.local)?\.json$|(?:^|\/)\.flow-agents\/lifecycle-authority-keys\.json$|(?:^|\/)(?:\.kontourai\/flow-agents|\.flow-agents)\/current\.json$|(?:^|\/)(?:\.kontourai\/flow-agents|\.flow-agents)\/current\/[^/]+\.json$|(?:^|\/)(?:\.kontourai\/flow-agents|\.flow-agents)\/\.goal-fit-block-streak\.json$|(?:^|\/)(?:\.kontourai\/flow-agents|\.flow-agents)\/[^/]+\/state\.json$|(?:^|\/)(?:\.kontourai\/flow-agents|\.flow-agents)\/[^/]+\/trust\.bundle$|(?:^|\/)delivery\/(?:[^/]+\/)?trust\.bundle$|(?:^|\/)delivery\/(?:[^/]+\/)?trust\.checkpoint\.json$/;
|
|
430
437
|
|
|
431
438
|
/**
|
|
432
439
|
* Return true when a token (an unquoted redirect target or tee argument) matches
|
|
@@ -20,6 +20,8 @@ const SANCTIONED_REMEDIES = {
|
|
|
20
20
|
'There is no sanctioned automated writer for this file. Ask a human maintainer to edit it directly. Never disable this hook to make the write.',
|
|
21
21
|
'.claude/settings.local.json':
|
|
22
22
|
'There is no sanctioned automated writer for this file. Ask a human maintainer to edit it directly. Never disable this hook to make the write.',
|
|
23
|
+
'.flow-agents/lifecycle-authority-keys.json':
|
|
24
|
+
'Only the trusted harness installer or a human maintainer may rotate lifecycle authority keys. Never let an agent replace this trust root.',
|
|
23
25
|
'.kontourai/flow-agents/current.json':
|
|
24
26
|
'Use `npm run workflow:sidecar -- ensure-session` (or `advance-state`), which writes this file for you. Never disable this hook to make the write.',
|
|
25
27
|
'.kontourai/flow-agents/current/<actor>.json':
|
|
@@ -58,6 +60,7 @@ function remedyFor(name) {
|
|
|
58
60
|
* basename 'trust.bundle') -- first match wins, deterministically.
|
|
59
61
|
*/
|
|
60
62
|
const REMEDY_COMMAND_CANDIDATES = [
|
|
63
|
+
{ name: '.flow-agents/lifecycle-authority-keys.json', needles: ['lifecycle-authority-keys.json'] },
|
|
61
64
|
{ name: 'delivery/trust.checkpoint.json', needles: ['delivery/trust.checkpoint.json', 'trust.checkpoint.json'] },
|
|
62
65
|
{ name: 'delivery/trust.bundle', needles: ['delivery/trust.bundle'] },
|
|
63
66
|
{ name: '.kontourai/flow-agents/<slug>/trust.bundle', needles: ['trust.bundle'] },
|
|
@@ -77,7 +77,7 @@ const PRE_EXECUTION_PHASES = new Set(['idea', 'backlog', 'pickup', 'planning']);
|
|
|
77
77
|
// Terminal tasks are complete — they must never gate a stop or count as "active".
|
|
78
78
|
// A stale current.json pointing at one, or a graveyard of finished states, must
|
|
79
79
|
// not block an unrelated session.
|
|
80
|
-
const TERMINAL_STATUSES = new Set(['done', 'delivered', 'accepted', 'archived', 'complete', 'completed']);
|
|
80
|
+
const TERMINAL_STATUSES = new Set(['done', 'delivered', 'canceled', 'accepted', 'archived', 'complete', 'completed']);
|
|
81
81
|
|
|
82
82
|
function isTerminalDeliveredState(state) {
|
|
83
83
|
if (!state || typeof state !== 'object') return false;
|
package/docs/context-map.md
CHANGED
|
@@ -54,8 +54,10 @@ Machine-readable workflow state lives beside Markdown artifacts in `.kontourai/f
|
|
|
54
54
|
| --- | --- | --- |
|
|
55
55
|
| assignment-provider-settings.schema.json | Flow Agents Assignment Provider Settings | https://flow-agents.dev/schemas/assignment-provider-settings.schema.json |
|
|
56
56
|
| backlog-provider-settings.schema.json | Flow Agents Backlog Provider Settings | https://flow-agents.dev/schemas/backlog-provider-settings.schema.json |
|
|
57
|
+
| builder-lifecycle-authorization.schema.json | Builder Lifecycle Authorization | https://kontourai.dev/schemas/builder-lifecycle-authorization.schema.json |
|
|
57
58
|
| decision-record.schema.json | Flow Agents Decision Record | https://flow-agents.dev/schemas/decision-record.schema.json |
|
|
58
59
|
| flow-agents-settings.schema.json | Flow Agents Settings | https://flow-agents.dev/schemas/flow-agents-settings.schema.json |
|
|
60
|
+
| lifecycle-authority-keys.schema.json | Lifecycle Authority Key Registry | https://kontourai.dev/schemas/lifecycle-authority-keys.schema.json |
|
|
59
61
|
| workflow-acceptance.schema.json | Flow Agents Workflow Acceptance | https://flow-agents.dev/schemas/workflow-acceptance.schema.json |
|
|
60
62
|
| workflow-critique.schema.json | Flow Agents Workflow Critique | https://flow-agents.dev/schemas/workflow-critique.schema.json |
|
|
61
63
|
| workflow-evidence.schema.json | Flow Agents Workflow Evidence | https://flow-agents.dev/schemas/workflow-evidence.schema.json |
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Public Workflow CLI
|
|
2
|
+
|
|
3
|
+
Flow Agents exposes its supported consumer workflow surface through the primary package binary.
|
|
4
|
+
Consumer repositories do not need a `package.json`, a local dependency, or a repository-owned
|
|
5
|
+
writer script.
|
|
6
|
+
|
|
7
|
+
Use an exact package version from an isolated npm prefix. This prevents a repository-local
|
|
8
|
+
dependency with the same version from intercepting the command. Generated workflow actions and
|
|
9
|
+
doctor remediation include this isolation automatically:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
flow_agents() (
|
|
13
|
+
root=$(mktemp -d) || exit 1
|
|
14
|
+
trap 'rm -rf "$root"' EXIT HUP INT TERM
|
|
15
|
+
npm exec --yes --prefix "$root" \
|
|
16
|
+
--package=@kontourai/flow-agents@3.5.0 -- flow-agents "$@"
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
flow_agents workflow start \
|
|
20
|
+
--flow builder.build \
|
|
21
|
+
--work-item owner/repository#123
|
|
22
|
+
|
|
23
|
+
flow_agents workflow status --json
|
|
24
|
+
|
|
25
|
+
flow_agents workflow evidence \
|
|
26
|
+
--expectation implementation-plan \
|
|
27
|
+
--status pass \
|
|
28
|
+
--summary "Implementation plan recorded." \
|
|
29
|
+
--evidence-ref-json '{"kind":"artifact","file":".kontourai/flow-agents/example/example--plan.md"}'
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The public lifecycle verbs are `pause`, `resume`, `release`, `cancel`, and `archive`. Pause,
|
|
33
|
+
resume, and release require the current assignment actor and an explicit reason. Cancel and
|
|
34
|
+
archive require a signed user/operator authorization file. Flow owns the canonical run
|
|
35
|
+
transition; Flow Agents validates assignment and request binding and projects the resulting run.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
flow_agents workflow pause --reason "Waiting for a decision"
|
|
39
|
+
flow_agents workflow resume --reason "Decision received"
|
|
40
|
+
flow_agents workflow release --reason "Handing work back"
|
|
41
|
+
flow_agents workflow cancel --authorization-file cancel.json
|
|
42
|
+
flow_agents workflow archive --authorization-file archive.json
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`workflow status` is read-only. It reads the actor-scoped current-session pointer, the projected
|
|
46
|
+
state, and the canonical Flow run without rewriting either store.
|
|
47
|
+
|
|
48
|
+
## Compatibility Doctor
|
|
49
|
+
|
|
50
|
+
Run doctor through the exact isolated package helper defined above:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
flow_agents workflow doctor --json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The report distinguishes the executing CLI from a repository-local dependency and reports the
|
|
57
|
+
workflow/writer contract, installed hook and writer package, active Kits, Builder Kit content,
|
|
58
|
+
Flow runtime and definition, workflow-state schema, and trust-bundle schema. Incompatible or
|
|
59
|
+
missing installed components produce a nonzero exit and an exact, version-pinned `init` command
|
|
60
|
+
that preserves the recorded runtime and active Kits.
|
|
61
|
+
|
|
62
|
+
The `flow-agents-workflow-sidecar` binary is deprecated and retained only while package-internal
|
|
63
|
+
callers migrate. New consumer guidance must use `flow-agents workflow`.
|
|
@@ -36,11 +36,18 @@ flow-agents builder-run start --session-dir .kontourai/flow-agents/<slug>
|
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
`ensure-session --flow-id builder.build` starts or loads this canonical run before
|
|
39
|
-
returning
|
|
40
|
-
the
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
returning. When the local assignment provider durably assigns the exact Work Item
|
|
40
|
+
to the resolved workflow actor, `ensure-session` rereads that record and produces
|
|
41
|
+
the declared `builder.pull-work.selected` claim through the normal Surface trust
|
|
42
|
+
bundle path. Flow evaluates that subject-bound evidence and advances to
|
|
43
|
+
`design-probe`; Flow Agents does not write a transition or gate outcome directly.
|
|
44
|
+
Skipped ownership, unresolved actors, precomputed state, and non-local providers do
|
|
45
|
+
not produce selection evidence and remain at `pull-work`.
|
|
46
|
+
|
|
47
|
+
The command remains the explicit recovery path if Flow startup fails after sidecar
|
|
48
|
+
creation; the failure is returned to the caller and no substitute run state is
|
|
49
|
+
invented. Runtime hooks keep projected actions advisory while the agent performs
|
|
50
|
+
their declared skills and operations.
|
|
44
51
|
|
|
45
52
|
Sidecars written by 3.4.2 may still contain `next_action.enforcement`. The 1.0
|
|
46
53
|
schema accepts that deprecated field for artifact compatibility, but current
|
|
@@ -111,3 +118,40 @@ Workflow steering surfaces these fields on session start and prompt submission.
|
|
|
111
118
|
Stop hook treats an unfinished canonical Flow run as active even during pickup or
|
|
112
119
|
planning, blocks a premature stop in block mode, and does not release its liveness
|
|
113
120
|
claim. A run is complete only when Flow reaches its terminal step.
|
|
121
|
+
# Builder Lifecycle Authority
|
|
122
|
+
|
|
123
|
+
The canonical Flow run owns pause, resume, and cancellation. The current assignment actor may
|
|
124
|
+
pause, resume, or release its own assignment with a reason. Cancellation and archival require
|
|
125
|
+
an Ed25519-signed authorization record conforming to
|
|
126
|
+
`schemas/builder-lifecycle-authorization.schema.json`. The record is operation-bound and binds
|
|
127
|
+
the request to the run id, selected Work Item, current assignment actor, immutable external
|
|
128
|
+
request reference, nonce, and expiry. Its signing key must be pinned in the durable
|
|
129
|
+
`.flow-agents/lifecycle-authority-keys.json` registry. Runtime or harness adapters hold the
|
|
130
|
+
private key and capture the signed record from a user/operator channel they trust; agent-authored
|
|
131
|
+
prose or an unsigned model-written file is not cancellation authority.
|
|
132
|
+
|
|
133
|
+
This is an audit and policy boundary, not authentication against a process with unrestricted
|
|
134
|
+
access as the same operating-system user. The harness must keep its signing key outside the
|
|
135
|
+
agent process and enforce its own filesystem or process isolation when the agent is adversarial.
|
|
136
|
+
The repository hooks protect the pinned public-key registry from ordinary agent writes, but are
|
|
137
|
+
explicitly not an operating-system security boundary.
|
|
138
|
+
Adversarial-runtime authentication is tracked separately in Flow Agents issue #545. Flow's
|
|
139
|
+
current lifecycle authority vocabulary also requires agent-owned pause/resume events to use the
|
|
140
|
+
closest available `operator_request` shape; a distinct canonical runtime authority is tracked in
|
|
141
|
+
Flow issue #118.
|
|
142
|
+
|
|
143
|
+
```text
|
|
144
|
+
flow-agents builder-run pause --session-dir <dir> --reason <text>
|
|
145
|
+
flow-agents builder-run resume --session-dir <dir> --reason <text>
|
|
146
|
+
flow-agents builder-run cancel --session-dir <dir> --authorization-file <record.json>
|
|
147
|
+
flow-agents builder-run release-assignment --session-dir <dir> --reason <text>
|
|
148
|
+
flow-agents builder-run archive --session-dir <dir> --authorization-file <record.json>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Pause and resume verify the live assignment actor under the assignment lock, and preserve the
|
|
152
|
+
current Flow step and assignment. Assignment release does not
|
|
153
|
+
change the Flow run. Cancellation changes Flow first and then idempotently releases the owning
|
|
154
|
+
assignment while holding the same lock; a successfully consumed cancellation nonce cannot be
|
|
155
|
+
replayed. Archive accepts only completed or canceled runs, moves the session under
|
|
156
|
+
`.kontourai/flow-agents/archive/<slug>/`, and retains the canonical Flow run. None of these
|
|
157
|
+
operations deletes a branch or worktree; cleanup requires a separate provider-aware action.
|
|
@@ -4,6 +4,11 @@ title: Workflow Usage Guide
|
|
|
4
4
|
|
|
5
5
|
# Workflow Usage Guide
|
|
6
6
|
|
|
7
|
+
> Consumer repositories should use the supported public workflow surface and isolated exact-package
|
|
8
|
+
> launcher documented in [Public Workflow CLI](public-workflow-cli.md). The lower-level writer
|
|
9
|
+
> commands retained later in this guide describe internal/package migration mechanics and are not a
|
|
10
|
+
> consumer prerequisite.
|
|
11
|
+
|
|
7
12
|
This guide shows how to use the Builder Kit workflow skills in normal chats.
|
|
8
13
|
|
|
9
14
|
> **Which doc do I want?** This page is the *driver's manual* — what to say at each stage and what should happen. If you want the conceptual map first — layers, sidecars, hooks, evidence, and why the system is shaped this way — read the [Agent System Guidebook](agent-system-guidebook.md). For a one-line summary of every skill and gate, use the [Skills Map](skills-map.md). Flow Agents coordinates the local runtime, installs Flow Kits, and records artifacts; Flow owns gate semantics, including typed `expects` entries with `kind: "trust.bundle"`, trusted producer config, and gate overrides.
|
package/evals/ci/run-baseline.sh
CHANGED
|
@@ -41,6 +41,7 @@ CHECKS=(
|
|
|
41
41
|
"Flow Kit repository integration|bash evals/integration/test_flow_kit_repository.sh"
|
|
42
42
|
"Runtime adapter activation integration|bash evals/integration/test_runtime_adapter_activation.sh"
|
|
43
43
|
"Bundle install integration|bash evals/integration/test_bundle_install.sh"
|
|
44
|
+
"Public workflow CLI integration|bash evals/integration/test_public_workflow_cli.sh"
|
|
44
45
|
"Bundle lifecycle integration|bash evals/integration/test_bundle_lifecycle.sh"
|
|
45
46
|
"Activate npx context integration|bash evals/integration/test_activate_npx_context.sh"
|
|
46
47
|
"Kit conformance levels integration|bash evals/integration/test_kit_conformance_levels.sh"
|
|
@@ -133,6 +134,7 @@ LANE_RUNTIME_AND_KIT=(
|
|
|
133
134
|
"Flow Kit repository integration"
|
|
134
135
|
"Runtime adapter activation integration"
|
|
135
136
|
"Bundle install integration"
|
|
137
|
+
"Public workflow CLI integration"
|
|
136
138
|
"Bundle lifecycle integration"
|
|
137
139
|
"Activate npx context integration"
|
|
138
140
|
"Kit conformance levels integration"
|
|
@@ -69,6 +69,60 @@ node "$CLI" assignment-provider status \
|
|
|
69
69
|
[[ "$(json_query "$TMPDIR_EVAL/status-a.json" "assignment.assignee")" == "claude-code:eval-actor-a-session:eval-host" ]] && pass "status reports actor A as assignee" || fail "status reports actor A as assignee"
|
|
70
70
|
[[ "$(json_query "$TMPDIR_EVAL/status-a.json" "assignment.record.claimed_at")" == "$CLAIMED_AT" ]] && pass "status claimed_at matches claim's claimed_at" || fail "status claimed_at matches claim's claimed_at"
|
|
71
71
|
|
|
72
|
+
# A generic same-actor refresh must preserve exact Builder provenance that an interrupted
|
|
73
|
+
# ensure-session recorded, even though the assignment-provider CLI does not accept that field.
|
|
74
|
+
PROVENANCE_SUBJECT="builder-provenance"
|
|
75
|
+
node "$CLI" assignment-provider claim \
|
|
76
|
+
--provider local-file --artifact-root "$ARTIFACT_ROOT" \
|
|
77
|
+
--subject-id "$PROVENANCE_SUBJECT" \
|
|
78
|
+
--actor-json "$ACTOR_A" \
|
|
79
|
+
--branch "$BRANCH_A" \
|
|
80
|
+
--artifact-dir "$ARTIFACT_DIR_A" \
|
|
81
|
+
--ttl-seconds 1800 \
|
|
82
|
+
> "$TMPDIR_EVAL/provenance-claim.json"
|
|
83
|
+
PROVENANCE_FILE="$(node - "$ARTIFACT_ROOT/assignment" "$PROVENANCE_SUBJECT" <<'NODE'
|
|
84
|
+
const fs = require('node:fs');
|
|
85
|
+
const path = require('node:path');
|
|
86
|
+
const [dir, subject] = process.argv.slice(2);
|
|
87
|
+
for (const name of fs.readdirSync(dir)) {
|
|
88
|
+
if (!name.endsWith('.json')) continue;
|
|
89
|
+
const file = path.join(dir, name);
|
|
90
|
+
if (JSON.parse(fs.readFileSync(file, 'utf8')).subject_id === subject) {
|
|
91
|
+
process.stdout.write(file);
|
|
92
|
+
process.exit(0);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
process.exit(1);
|
|
96
|
+
NODE
|
|
97
|
+
)"
|
|
98
|
+
node - "$PROVENANCE_FILE" <<'NODE'
|
|
99
|
+
const fs = require('node:fs');
|
|
100
|
+
const file = process.argv[2];
|
|
101
|
+
const record = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
102
|
+
record.work_item_ref = 'kontourai/flow-agents#9001';
|
|
103
|
+
fs.writeFileSync(file, `${JSON.stringify(record, null, 2)}\n`);
|
|
104
|
+
NODE
|
|
105
|
+
node "$CLI" assignment-provider claim \
|
|
106
|
+
--provider local-file --artifact-root "$ARTIFACT_ROOT" \
|
|
107
|
+
--subject-id "$PROVENANCE_SUBJECT" \
|
|
108
|
+
--actor-json "$ACTOR_A" \
|
|
109
|
+
--branch "$BRANCH_A" \
|
|
110
|
+
--artifact-dir "$ARTIFACT_DIR_A" \
|
|
111
|
+
--ttl-seconds 1800 \
|
|
112
|
+
> "$TMPDIR_EVAL/provenance-refresh.json"
|
|
113
|
+
[[ "$(json_query "$TMPDIR_EVAL/provenance-refresh.json" "record.work_item_ref")" == "$SUBJECT_ID" ]] && pass "same-actor refresh preserves exact Work Item provenance" || fail "same-actor refresh preserves exact Work Item provenance"
|
|
114
|
+
node "$CLI" assignment-provider supersede \
|
|
115
|
+
--provider local-file --artifact-root "$ARTIFACT_ROOT" \
|
|
116
|
+
--subject-id "$PROVENANCE_SUBJECT" \
|
|
117
|
+
--from-actor-json "$ACTOR_A" --to-actor-json "$ACTOR_B" \
|
|
118
|
+
--reason "provenance handoff" >"$TMPDIR_EVAL/provenance-supersede.json"
|
|
119
|
+
[[ "$(json_query "$TMPDIR_EVAL/provenance-supersede.json" "record.work_item_ref")" == "$SUBJECT_ID" ]] && pass "generic supersede preserves exact Work Item provenance" || fail "generic supersede preserves exact Work Item provenance"
|
|
120
|
+
node "$CLI" assignment-provider release \
|
|
121
|
+
--provider local-file --artifact-root "$ARTIFACT_ROOT" \
|
|
122
|
+
--subject-id "$PROVENANCE_SUBJECT" \
|
|
123
|
+
--actor-json "$ACTOR_B" \
|
|
124
|
+
--reason "provenance fixture cleanup" >/dev/null
|
|
125
|
+
|
|
72
126
|
# 3. supersede A -> B updates the actor and records an audit trail entry.
|
|
73
127
|
node "$CLI" assignment-provider supersede \
|
|
74
128
|
--provider local-file --artifact-root "$ARTIFACT_ROOT" --subject-id "$SUBJECT_ID" \
|