@kontourai/flow-agents 0.1.1 → 0.1.2

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.
@@ -57,7 +57,7 @@ jobs:
57
57
  - name: Set up Node.js
58
58
  uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
59
59
  with:
60
- node-version: "22"
60
+ node-version: "24"
61
61
  registry-url: "https://registry.npmjs.org"
62
62
 
63
63
  - name: Install dependencies
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.2
4
+
5
+ - Source validation resolves the Flow CLI at `dist/cli.js` (with a
6
+ `src/cli.js` fallback), and the source-and-static CI lane installs
7
+ `@kontourai/flow` so kit Flow Definitions are validated by the real
8
+ Flow CLI.
9
+ - The publish workflow builds the bundle explicitly before `npm publish`.
10
+ - Docs routing between the System Guidebook and the Workflow Usage Guide;
11
+ duplicated development walkthrough removed.
12
+ - README and Pages home advertise the npm install with the version badge;
13
+ pre-release caveats removed; Kontour family table links product pages
14
+ and gains a Survey row.
15
+ - Fixes phantom skill references, a stale pack list, and path accuracy in
16
+ the docs.
17
+
3
18
  ## 0.1.1
4
19
 
5
20
  ### Documentation And Site
package/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  **The discipline of Kontour Flow, inside the agent tools you already use.**
6
6
 
7
+ [![npm version](https://img.shields.io/npm/v/%40kontourai%2Fflow-agents)](https://www.npmjs.com/package/@kontourai/flow-agents)
7
8
  [![CI](https://github.com/kontourai/flow-agents/actions/workflows/ci.yml/badge.svg)](https://github.com/kontourai/flow-agents/actions/workflows/ci.yml)
8
9
  [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
9
10
  [![Node >= 22](https://img.shields.io/badge/node-%3E%3D22-brightgreen)](package.json)
@@ -42,13 +43,7 @@ npx @kontourai/flow-agents init --dest /path/to/workspace --telemetry-sink local
42
43
  npx @kontourai/flow-agents init --runtime codex --dest /path/to/workspace --activate-kits --yes
43
44
  ```
44
45
 
45
- Until the first npm release lands, the same commands work from a checkout:
46
-
47
- ```bash
48
- git clone https://github.com/kontourai/flow-agents.git
49
- cd flow-agents && npm install && npm run build
50
- node build/src/cli.js init --dest /path/to/workspace
51
- ```
46
+ Working from a checkout (for contributors) is the same flow: `npm install && npm run build`, then `node build/src/cli.js init --dest /path/to/workspace`.
52
47
 
53
48
  The installer copies the bundled agents, skills, context, scripts, evals, Flow Kit assets, and the Flow Agents-owned `console.telemetry.json` descriptor into the target workspace. Telemetry writes to local files by default; optional sinks mirror it to a local, hosted, or self-hosted Kontour Console (`--telemetry-sink local-kontour-console | kontour-hosted-console | user-hosted-console --console-url …`).
54
49
 
@@ -86,9 +81,10 @@ Kontour AI shows the work behind AI. Each product stands alone; together they co
86
81
 
87
82
  | Product | Owns |
88
83
  | --- | --- |
89
- | **[Surface](https://github.com/kontourai/surface)** | Portable trust state: claims, evidence, policies, trust snapshots |
90
- | **[Flow](https://github.com/kontourai/flow)** | Process transparency: steps, gates, transitions, runs, exceptions, reports |
91
- | **[Veritas](https://github.com/kontourai/veritas)** | Code/change transparency: repo standards, merge readiness |
84
+ | **[Survey](https://kontourai.io/survey)** | Producer evidence: source extraction candidate → review → claim |
85
+ | **[Surface](https://kontourai.io/surface)** | Portable trust state: claims, evidence, policies, trust snapshots |
86
+ | **[Flow](https://kontourai.io/flow)** | Process transparency: steps, gates, transitions, runs, exceptions, reports |
87
+ | **[Veritas](https://kontourai.io/veritas)** | Code/change transparency: repo standards, merge readiness |
92
88
  | **Flow Agents** | Agent-facing distribution: skills, kits, runtime adapters, hooks, telemetry |
93
89
 
94
90
  Flow Agents owns the glue — discovery, just-in-time guidance, scoped delegation, Flow-backed state inside harnesses, evidence-backed completion, and feedback loops. It deliberately does not own the model, the runtime, the workflow engine, or repo governance. The [North Star](docs/north-star.md) records the direction and design principles.
@@ -0,0 +1,172 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { flagBool, flagString, parseArgs } from "../lib/args.js";
4
+ // ---------------------------------------------------------------------------
5
+ // Helpers
6
+ // ---------------------------------------------------------------------------
7
+ function usage() {
8
+ console.error([
9
+ "usage: flow-agents utterance-check check [options]",
10
+ "",
11
+ "Check an agent utterance for evidence coverage using @kontourai/survey.",
12
+ "Requires @kontourai/survey to be installed in the target workspace.",
13
+ "",
14
+ "Options:",
15
+ " --utterance TEXT Utterance text to check (required unless --not-configured).",
16
+ " --bundle-path FILE Trust bundle JSON file. Omit for an empty bundle (all unsupported).",
17
+ " --agent-id ID Agent identifier for provenance (default: flow-agents-utterance-check).",
18
+ " --not-configured Skip survey call; output not_configured without error.",
19
+ " --strict Exit non-zero when any badge is disputed, rejected, or unsupported.",
20
+ " --help Show this help.",
21
+ ].join("\n"));
22
+ }
23
+ function excerptText(text, maxLen = 200) {
24
+ const trimmed = text.trim().replace(/\s+/g, " ");
25
+ return trimmed.length > maxLen ? `${trimmed.slice(0, maxLen - 3)}...` : trimmed;
26
+ }
27
+ function badgeSummary(statements) {
28
+ if (statements.length === 0)
29
+ return "no factual statements extracted";
30
+ const counts = {};
31
+ for (const s of statements) {
32
+ counts[s.badge] = (counts[s.badge] ?? 0) + 1;
33
+ }
34
+ return Object.entries(counts)
35
+ .sort((a, b) => b[1] - a[1])
36
+ .map(([badge, n]) => `${badge}:${n}`)
37
+ .join(", ");
38
+ }
39
+ function hasConcerningBadge(badge) {
40
+ return badge === "disputed" || badge === "rejected" || badge === "unsupported";
41
+ }
42
+ async function loadSurvey() {
43
+ try {
44
+ const pkg = "@kontourai/survey";
45
+ // Dynamic import avoids a static dependency on @kontourai/survey —
46
+ // the same pattern survey/src/anthropic.ts uses for @anthropic-ai/sdk.
47
+ const mod = await Function("m", "return import(m)")(pkg);
48
+ return mod;
49
+ }
50
+ catch {
51
+ return undefined;
52
+ }
53
+ }
54
+ // ---------------------------------------------------------------------------
55
+ // Core check logic
56
+ // ---------------------------------------------------------------------------
57
+ async function runCheck(argv) {
58
+ const { flags } = parseArgs(argv);
59
+ if (flagBool(flags, "help")) {
60
+ usage();
61
+ return 0;
62
+ }
63
+ const agentId = flagString(flags, "agent-id") ?? "flow-agents-utterance-check";
64
+ const notConfigured = flagBool(flags, "not-configured");
65
+ const strict = flagBool(flags, "strict");
66
+ if (notConfigured) {
67
+ const report = {
68
+ status: "not_configured",
69
+ agent_id: agentId,
70
+ utterance_excerpt: "",
71
+ statements: [],
72
+ summary: "@kontourai/survey is not configured for this workspace.",
73
+ };
74
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
75
+ return 0;
76
+ }
77
+ const utterance = flagString(flags, "utterance");
78
+ if (!utterance) {
79
+ usage();
80
+ return 3;
81
+ }
82
+ const bundlePath = flagString(flags, "bundle-path");
83
+ let bundle = { claims: [] };
84
+ if (bundlePath) {
85
+ const resolved = path.resolve(bundlePath);
86
+ try {
87
+ const raw = fs.readFileSync(resolved, "utf8");
88
+ bundle = JSON.parse(raw);
89
+ }
90
+ catch (err) {
91
+ const msg = err instanceof Error ? err.message : String(err);
92
+ process.stderr.write(`[UtteranceCheck] could not read bundle from ${resolved}: ${msg}\n`);
93
+ }
94
+ }
95
+ const survey = await loadSurvey();
96
+ if (!survey) {
97
+ const report = {
98
+ status: "not_configured",
99
+ agent_id: agentId,
100
+ utterance_excerpt: excerptText(utterance),
101
+ statements: [],
102
+ summary: "@kontourai/survey is not installed. Install it or run with --not-configured.",
103
+ };
104
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
105
+ process.stderr.write("[UtteranceCheck] not_configured: @kontourai/survey is not installed in this workspace.\n");
106
+ return 1;
107
+ }
108
+ const { surveyAgentUtterance, referenceUtteranceExtractor } = survey;
109
+ let trustReport;
110
+ try {
111
+ trustReport = await surveyAgentUtterance(utterance, referenceUtteranceExtractor, {
112
+ bundle,
113
+ agentId,
114
+ });
115
+ }
116
+ catch (err) {
117
+ const msg = err instanceof Error ? err.message : String(err);
118
+ const report = {
119
+ status: "error",
120
+ agent_id: agentId,
121
+ utterance_excerpt: excerptText(utterance),
122
+ statements: [],
123
+ summary: `Survey call failed: ${msg}`,
124
+ };
125
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
126
+ process.stderr.write(`[UtteranceCheck] survey call failed: ${msg}\n`);
127
+ return 1;
128
+ }
129
+ const statements = trustReport.statements.map((s) => ({
130
+ excerpt: s.excerpt,
131
+ badge: s.badge,
132
+ target: s.target,
133
+ span: s.span,
134
+ }));
135
+ const summary = badgeSummary(statements);
136
+ const report = {
137
+ status: "ok",
138
+ agent_id: agentId,
139
+ utterance_excerpt: excerptText(utterance),
140
+ statements,
141
+ summary,
142
+ };
143
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
144
+ const concerning = statements.filter((s) => hasConcerningBadge(s.badge));
145
+ if (concerning.length > 0) {
146
+ process.stderr.write(`[UtteranceCheck] ${concerning.length} statement(s) lack evidence coverage: ${summary}\n`);
147
+ for (const s of concerning.slice(0, 4)) {
148
+ process.stderr.write(` - [${s.badge}] "${excerptText(s.excerpt, 100)}"\n`);
149
+ }
150
+ }
151
+ if (strict && concerning.length > 0)
152
+ return 2;
153
+ return 0;
154
+ }
155
+ // ---------------------------------------------------------------------------
156
+ // Entry point
157
+ // ---------------------------------------------------------------------------
158
+ export async function main(argv = process.argv.slice(2)) {
159
+ const [subcommand, ...rest] = argv;
160
+ if (!subcommand || subcommand === "--help" || subcommand === "-h") {
161
+ usage();
162
+ return 0;
163
+ }
164
+ if (subcommand !== "check") {
165
+ console.error(`Unknown utterance-check subcommand: ${subcommand}`);
166
+ usage();
167
+ return 3;
168
+ }
169
+ return runCheck(rest);
170
+ }
171
+ if (import.meta.url === `file://${process.argv[1]}`)
172
+ process.exit(await main());
package/build/src/cli.js CHANGED
@@ -19,6 +19,7 @@ import { main as validateSource } from "./tools/validate-source-tree.js";
19
19
  import { main as validatePackage } from "./tools/validate-package.js";
20
20
  import { main as validateHookInfluence } from "./cli/validate-hook-influence.js";
21
21
  import { main as runtimeAdapter } from "./cli/runtime-adapter.js";
22
+ import { main as utteranceCheck } from "./cli/utterance-check.js";
22
23
  const availableCommands = new Map([
23
24
  ["build-bundles", () => buildBundles()],
24
25
  ["console-learning-projection", consoleLearningProjection],
@@ -32,6 +33,7 @@ const availableCommands = new Map([
32
33
  ["publish-change", publishChange],
33
34
  ["pull-work-provider", pullWorkProvider],
34
35
  ["runtime-adapter", runtimeAdapter],
36
+ ["utterance-check", utteranceCheck],
35
37
  ["telemetry-doctor", telemetryDoctor],
36
38
  ["usage-feedback", usageFeedback],
37
39
  ["veritas-governance", veritasGovernance],
@@ -56,6 +58,7 @@ const aliases = new Map([
56
58
  ["flow-agents-usage-feedback", "usage-feedback"],
57
59
  ["flow-agents-veritas-governance", "veritas-governance"],
58
60
  ["flow-agents-validate-hook-influence", "validate-hook-influence"],
61
+ ["flow-agents-utterance-check", "utterance-check"],
59
62
  ["flow-agents-validate-source", "validate-source"],
60
63
  ["flow-agents-workflow-artifact-cleanup-audit", "workflow-artifact-cleanup-audit"],
61
64
  ]);
@@ -68,6 +68,7 @@ const hookFilePolicies = new Map([
68
68
  ["scripts/hooks/report-only-guard.js", { category: "policy hook", requiredNeedles: ["Report-Only Guard Hook"] }],
69
69
  ["scripts/hooks/stop-format-typecheck.js", { category: "policy hook", requiredNeedles: ["Stop Hook", "typecheck"] }],
70
70
  ["scripts/hooks/stop-goal-fit.js", { category: "policy hook", requiredNeedles: ["Stop Hook", "Goal Fit"] }],
71
+ ["scripts/hooks/utterance-check.js", { category: "policy hook", requiredNeedles: ["Utterance Check Hook", "FLOW_AGENTS_UTTERANCE_CHECK_ENABLED"] }],
71
72
  ["scripts/hooks/workflow-steering.js", { category: "policy hook", requiredNeedles: ["Workflow Steering Hook"] }],
72
73
  ["scripts/hooks/desktop-notify.sh", { category: "local notification helper", requiredNeedles: ["desktop-notify.sh", "osascript"] }],
73
74
  ["scripts/hooks/lib/audit-transport.sh", { category: "shared hook library", requiredNeedles: ["audit_emit"] }],
@@ -86,7 +86,7 @@ Flow Agents works like an agent workbench with seven cooperating layers:
86
86
  | Powers | Tool bundles and activation guidance for integrations. | `powers/` |
87
87
  | Agents | Specialist roles with scoped responsibilities. | `agents/`, `agent-cards/` |
88
88
  | Workflows | State, gates, handoffs, and task memory. | Kontour Flow concepts, `.flow-agents/`, `npm run workflow:sidecar --` |
89
- | Hooks | Just-in-time reminders or blockers from current workflow state. | `hooks/`, exported runtime configs |
89
+ | Hooks | Just-in-time reminders or blockers from current workflow state. | `scripts/hooks/`, exported runtime configs |
90
90
  | Evidence | Tests, evals, telemetry, findings, and outcome records. | `evals/`, `.telemetry/`, sidecars |
91
91
 
92
92
  Each layer should stay small enough to explain independently. When the system feels complicated, the fix is usually to move behavior to the right layer, not to add more global prompt text.
@@ -252,13 +252,12 @@ The intended pattern is that every important workflow rule gets a test at the lo
252
252
 
253
253
  Packs keep the global surface understandable.
254
254
 
255
- `packaging/packs.json` groups capabilities into sets such as:
255
+ `packaging/packs.json` groups capabilities into sets. Currently defined:
256
256
 
257
257
  - `core`
258
258
  - `development`
259
- - `knowledge`
260
- - `aws`
261
- - `experimental`
259
+
260
+ Future packs (knowledge, AWS, experimental) are deferred until another producer proof shows repeated friction.
262
261
 
263
262
  All-pack installs remain the default today. `FLOW_AGENTS_PACKS` lets users opt into a smaller installed surface, and domain depth belongs in packs so a global setup can be narrowed without changing the source bundle.
264
263
 
package/docs/index.md CHANGED
@@ -49,7 +49,6 @@ Flow Agents adds the operating layer around the model: skills choose the right w
49
49
  npx @kontourai/flow-agents init --dest /path/to/workspace
50
50
  ```
51
51
 
52
- Until the first npm release lands, the same command works from a checkout: clone the repo, `npm install && npm run build`, then `node build/src/cli.js init --dest /path/to/workspace`.
53
52
 
54
53
  Then ask for the workflow you want, in plain language:
55
54
 
@@ -122,7 +121,7 @@ Use fix-bug. Reproduce the problem, diagnose root cause, implement the fix, and
122
121
 
123
122
  ## The Kontour family
124
123
 
125
- Kontour AI shows the work behind AI. <a href="https://kontourai.github.io/flow/">Flow</a> proves why a process was allowed to advance. Veritas makes AI-authored code changes inspectable. Flow Agents packages those foundations into the agent tools you already use — so trustworthy autonomy doesn't require a perfect prompt, perfect memory, or a new runtime.
124
+ Kontour AI shows the work behind AI. <a href="https://kontourai.github.io/flow/">Flow</a> proves why a process was allowed to advance. <a href="https://kontourai.io/veritas">Veritas</a> makes AI-authored code changes inspectable. <a href="https://kontourai.io/survey">Survey</a> and <a href="https://kontourai.io/surface">Surface</a> carry the evidence underneath. Flow Agents packages those foundations into the agent tools you already use — so trustworthy autonomy doesn't require a perfect prompt, perfect memory, or a new runtime.
126
125
 
127
126
  ## Why it matters
128
127
 
@@ -180,7 +180,7 @@ Tasks:
180
180
 
181
181
  - Document the public layers: rules, skills, powers, agents, workflows, knowledge, and evidence. **Done:** see https://github.com/kontourai/flow-agents/blob/main/docs/operating-layers.md.
182
182
  - Mark which directories are canonical source, generated exports, runtime state, and optional integrations.
183
- - Decide which workflow skills are part of the core pack and which are optional domain packs. **Started:** `packaging/packs.json` defines core, development, knowledge, AWS, and experimental packs.
183
+ - Decide which workflow skills are part of the core pack and which are optional domain packs. **Started:** `packaging/packs.json` defines core and development packs.
184
184
  - Add a standards register that lists each external standard, how Flow Agents uses it, and what Flow Agents-owned schemas still exist. **Done:** see https://github.com/kontourai/flow-agents/blob/main/docs/standards-register.md.
185
185
  - Add a "do not invent without checking standards" rule to contributor docs.
186
186
 
@@ -96,7 +96,7 @@ specific row that matches the change.
96
96
  | Bundle/export shape | `packaging/`, `src/tools/build-universal-bundles.ts`, and source directories copied into bundles | `bash evals/static/test_universal_bundles.sh` |
97
97
  | Installer or local runtime setup behavior | `scripts/install-*.sh`, package bins, and generated bundle install scripts | `bash evals/integration/test_bundle_install.sh` |
98
98
  | Workflow artifact, sidecar, or provider contract | `context/contracts/`, `schemas/`, `src/cli/workflow-*`, and matching eval fixtures | `npm run workflow:validate-artifacts --` and workflow integration evals |
99
- | Flow Kit catalog or bundled kit content | `kits/`, Flow Definition files, and kit repository fixtures | `npm run flow-kit -- validate` or `bash evals/integration/test_flow_kit_repository.sh` |
99
+ | Flow Kit catalog or bundled kit content | `kits/`, Flow Definition files, and kit repository fixtures | `npm run validate:source -- --kit <path>` or `bash evals/integration/test_flow_kit_repository.sh` |
100
100
  | Durable developer guidance | `docs/`; regenerate/check the context map when navigation or durable contracts change | `npm run context-map:check --` |
101
101
  | Eval scenario or fixture | `evals/static/`, `evals/integration/`, `evals/fixtures/`, or `evals/cases/` | The owning eval plus `bash evals/run.sh static` when contracts are touched |
102
102
  | Optional external integration configuration | `integrations/` or `veritas.claims.json`; keep local run output ignored | The integration-specific eval or documented dry run |
@@ -45,6 +45,9 @@ flowchart LR
45
45
  Learn -->|new work| Shape
46
46
  ```
47
47
 
48
+ > `publish-change` is a CLI-driven workflow step, not a loadable skill.
49
+ > `goal-fit` is a hook-enforced check, not a loadable skill.
50
+
48
51
  ## Current Shape
49
52
 
50
53
  The operating model now has first-class coverage from idea intake through trusted delivery:
@@ -76,7 +79,7 @@ This view shows how each phase is composed. The left rail is the durable phase s
76
79
  <div class="phase-step"><span>01</span><strong>Discovery & shaping</strong></div>
77
80
  <div class="phase-lanes">
78
81
  <section class="phase-lane phase-lane--primary"><h3>Primary</h3><p><code>builder-shape</code> <code>idea-to-backlog</code></p></section>
79
- <section class="phase-lane"><h3>Support</h3><p><code>knowledge-search</code> <code>search-first</code> <code>explore</code> <code>crowdsource</code> <code>frontend-design</code> <code>github-cli</code> <code>knowledge-capture</code></p></section>
82
+ <section class="phase-lane"><h3>Support</h3><p><code>search-first</code> <code>explore</code> <code>frontend-design</code> <code>github-cli</code> <code>knowledge-capture</code></p></section>
80
83
  <section class="phase-lane"><h3>Nested sections / future primitives</h3><p>intake/dedupe, separate ideas, thinnest meaningful slice, opportunity review, explore options, <code>shape-work</code>, prioritize work, sync executable backlog</p></section>
81
84
  <section class="phase-lane phase-lane--gate"><h3>Gate & artifact</h3><p>Idea, slice, shape, and backlog gates. Writes shaped briefs and GitHub issue links in <code>.flow-agents/&lt;slug&gt;/</code>.</p></section>
82
85
  </div>
@@ -112,7 +115,7 @@ This view shows how each phase is composed. The left rail is the durable phase s
112
115
  <div class="phase-step"><span>05</span><strong>Learning & improvement</strong></div>
113
116
  <div class="phase-lanes">
114
117
  <section class="phase-lane phase-lane--primary"><h3>Primary</h3><p><code>learning-review</code></p></section>
115
- <section class="phase-lane"><h3>Support</h3><p><code>knowledge-capture</code> <code>observe</code> <code>idea-to-backlog</code> <code>eval-rebuild</code></p></section>
118
+ <section class="phase-lane"><h3>Support</h3><p><code>knowledge-capture</code> <code>idea-to-backlog</code> <code>eval-rebuild</code></p></section>
116
119
  <section class="phase-lane"><h3>Nested sections / future primitives</h3><p>facts vs interpretation, follow-up routing, docs promotion review, knowledge updates, eval updates, skill/backlog improvements</p></section>
117
120
  <section class="phase-lane phase-lane--gate"><h3>Gate & artifact</h3><p>Learning gate. Writes outcomes, gaps, docs promotion state, follow-ups, knowledge updates, and verdict.</p></section>
118
121
  </div>
@@ -121,11 +124,11 @@ This view shows how each phase is composed. The left rail is the durable phase s
121
124
 
122
125
  | Phase | Primary workflow skill | Supporting skills | Nested sections / future primitive candidates |
123
126
  | --- | --- | --- | --- |
124
- | Idea discovery and shaping | `builder-shape`, `idea-to-backlog` | `knowledge-search`, `search-first`, `explore`, `crowdsource`, `frontend-design`, `github-cli`, `knowledge-capture` | intake/dedupe, separate ideas, thinnest meaningful slice, opportunity review, explore options, shape work, prioritize work, sync executable backlog |
127
+ | Idea discovery and shaping | `builder-shape`, `idea-to-backlog` | `search-first`, `explore`, `frontend-design`, `github-cli`, `knowledge-capture` | intake/dedupe, separate ideas, thinnest meaningful slice, opportunity review, explore options, shape work, prioritize work, sync executable backlog |
125
128
  | Backlog pickup | `pull-work` | `github-cli` | board snapshot, WIP check, grouping/dependency check, Probe decision, worktree decision, handoff |
126
129
  | Execution planning and build | `design-probe`, `pickup-probe`, `plan-work`, `execute-plan`, `review-work`, `verify-work` | `feedback-loop`, `browser-test`, `deliver`, `fix-bug`, `tdd-workflow` | Probe notes, Builder Kit Probe record, Definition Of Done, execution plan, parallel waves, implementation session state, critique report, verification report, Goal Fit Gate |
127
130
  | Evidence and release confidence | `evidence-gate`, `release-readiness` | `github-cli`, `eval-rebuild` | criteria-to-evidence map, CI confidence, scope/integrity check, publish-change, rollback review, observability review, final acceptance docs, post-deploy plan |
128
- | Learning and improvement | `learning-review` | `knowledge-capture`, `observe`, `idea-to-backlog`, `eval-rebuild` | facts vs interpretation, docs promotion review, follow-up routing, knowledge updates, eval/skill/backlog improvements |
131
+ | Learning and improvement | `learning-review` | `knowledge-capture`, `idea-to-backlog`, `eval-rebuild` | facts vs interpretation, docs promotion review, follow-up routing, knowledge updates, eval/skill/backlog improvements |
129
132
 
130
133
  The highest-leverage future extractions are likely `shape-work`, `test-map`, `scope-and-integrity-check`, and `remediate-ci`. They are still nested because their behavior is present, but not yet large enough to need separate activation contracts.
131
134
 
@@ -190,6 +193,9 @@ flowchart LR
190
193
  Learning -->|systemic change| Eval[eval-rebuild / backlog / skill update]
191
194
  ```
192
195
 
196
+ > `publish-change` is a CLI-driven workflow step, not a loadable skill.
197
+ > `goal-fit` is a hook-enforced check, not a loadable skill.
198
+
193
199
  ## Eval Coverage
194
200
 
195
201
  Workflow evals are layered to match this map:
@@ -0,0 +1,191 @@
1
+ ---
2
+ title: Survey Utterance Check Integration
3
+ ---
4
+
5
+ # Survey Utterance Check Integration
6
+
7
+ Flow Agents can optionally check agent utterances for evidence coverage using `@kontourai/survey`. This integration is disabled by default and intentionally optional — ordinary Flow Agents workflows do not require Survey.
8
+
9
+ The guiding rule mirrors the Veritas boundary: Flow Agents owns the hook wiring and badge guidance format; Survey owns the extraction, claim resolution, and trust report semantics.
10
+
11
+ ## Background: ADR 0003 §9
12
+
13
+ ADR 0003 §9 designates agent-utterance extraction as a **Survey producer profile** — Survey pointed at agent prose instead of web sources. Each factual statement in agent output is extracted as a candidate claim and run through Survey's Inquiry pipeline. Flow Agents supplies the enforcement point (hooks) that ADR 0003 calls out. This integration is step 6 of the ADR sequencing and depends on the Inquiry pipeline already existing in Survey.
14
+
15
+ ## User-Facing Story
16
+
17
+ ```text
18
+ Agent: "The test coverage for auth-service is 92%. All critical paths have been verified."
19
+
20
+ Flow Agents (hook active):
21
+ 1. Captures the agent's response text from the PostToolUse event.
22
+ 2. Invokes the utterance-check CLI adapter with the response text.
23
+ 3. @kontourai/survey extracts factual statements: coverage:92%, paths:verified.
24
+ 4. Survey resolves each statement against the configured trust bundle.
25
+ 5. Statements without matching claims resolve as "unsupported".
26
+ 6. Flow Agents injects badge guidance into the agent context:
27
+ UTTERANCE CHECK: 2 statement(s) lack evidence coverage.
28
+ - [unsupported] "test coverage for auth-service is 92%"
29
+ - [unsupported] "All critical paths have been verified"
30
+ ```
31
+
32
+ The agent sees honest gap disclosure rather than silent pass-through.
33
+
34
+ ## Ownership Split
35
+
36
+ | Area | Flow Agents Owns | Survey Owns |
37
+ | --- | --- | --- |
38
+ | Hook wiring | PostToolUse/Stop hook, badge guidance format, enable/disable flags | None |
39
+ | Extraction | Invoking the CLI adapter | Statement extraction, extractor interface |
40
+ | Resolution | Passing the trust bundle path | Inquiry pipeline, claim resolution |
41
+ | Output | Guidance text injected into agent context | UtteranceTrustReport with per-statement badges |
42
+ | Packaging | Optional hook activation, CLI adapter | @kontourai/survey npm package |
43
+
44
+ Flow Agents does not own trust claim models, inquiry semantics, or extractor implementations. Survey's `referenceUtteranceExtractor` is the default extractor; production use should inject `createAnthropicUtteranceExtractor` from `@kontourai/survey/anthropic` for model-backed extraction.
45
+
46
+ ## Enabling the Hook
47
+
48
+ The hook is disabled by default. Set environment variables before starting the agent session:
49
+
50
+ ```bash
51
+ export FLOW_AGENTS_UTTERANCE_CHECK_ENABLED=true
52
+
53
+ # Optional: path to a trust bundle JSON file for claim resolution
54
+ export FLOW_AGENTS_UTTERANCE_CHECK_BUNDLE_PATH=/path/to/trust-bundle.json
55
+
56
+ # Optional: agent identifier for provenance
57
+ export FLOW_AGENTS_UTTERANCE_CHECK_AGENT_ID=my-codex-session
58
+
59
+ # Optional: strict mode — blocks Stop when concerning badges are present
60
+ export FLOW_AGENTS_UTTERANCE_CHECK_STRICT=true
61
+ ```
62
+
63
+ The hook runs through the standard `run-hook.js` runner and respects `SA_DISABLED_HOOKS` and `SA_HOOK_PROFILE`.
64
+
65
+ ## CLI Adapter Contract
66
+
67
+ The utterance check CLI is available as:
68
+
69
+ ```bash
70
+ node build/src/cli.js utterance-check check \
71
+ --utterance "The coverage is 92% and all tests pass." \
72
+ --bundle-path .surface/trust-bundle.json \
73
+ --agent-id my-session
74
+ ```
75
+
76
+ Options:
77
+
78
+ ```
79
+ --utterance TEXT Utterance text to check (required unless --not-configured).
80
+ --bundle-path FILE Trust bundle JSON file. Omit for an empty bundle (all unsupported).
81
+ --agent-id ID Agent identifier for provenance (default: flow-agents-utterance-check).
82
+ --not-configured Skip survey call; output not_configured without error.
83
+ --strict Exit non-zero when any badge is disputed, rejected, or unsupported.
84
+ --help Show this help.
85
+ ```
86
+
87
+ The CLI outputs a JSON report to stdout:
88
+
89
+ ```json
90
+ {
91
+ "status": "ok",
92
+ "agent_id": "my-session",
93
+ "utterance_excerpt": "The coverage is 92% and all tests pass.",
94
+ "statements": [
95
+ {
96
+ "excerpt": "coverage is 92%",
97
+ "badge": "unsupported",
98
+ "target": {
99
+ "subjectType": "unknown",
100
+ "subjectId": "coverage",
101
+ "fieldOrBehavior": "is"
102
+ }
103
+ }
104
+ ],
105
+ "summary": "unsupported:2"
106
+ }
107
+ ```
108
+
109
+ Badge values:
110
+
111
+ | Badge | Meaning |
112
+ | --- | --- |
113
+ | `verified` | Matched a claim with verified status |
114
+ | `assumed` | Matched a claim with assumed status |
115
+ | `stale` | Matched a claim that is stale |
116
+ | `disputed` | Matched a claim with conflicting evidence |
117
+ | `rejected` | Matched a claim that was rejected |
118
+ | `unsupported` | No matching claim in the trust bundle |
119
+
120
+ Exit codes: `0` = pass, `1` = survey unavailable, `2` = strict mode with concerning badges, `3` = usage error.
121
+
122
+ When `@kontourai/survey` is not installed, the CLI outputs `status: "not_configured"` and exits `1`. The hook treats `not_configured` as a silent pass-through.
123
+
124
+ ## Registering the Hook
125
+
126
+ Add the utterance check to a Claude Code session via `.claude/settings.json`:
127
+
128
+ ```json
129
+ {
130
+ "hooks": {
131
+ "PostToolUse": [
132
+ {
133
+ "matcher": ".*",
134
+ "hooks": [
135
+ {
136
+ "type": "command",
137
+ "command": "node scripts/hooks/claude-hook-adapter.js PostToolUse post:utterance-check utterance-check.js standard,strict"
138
+ }
139
+ ]
140
+ }
141
+ ]
142
+ }
143
+ }
144
+ ```
145
+
146
+ Or run the hook directly (Kiro/Codex convention, exit 2 blocks):
147
+
148
+ ```bash
149
+ node scripts/hooks/run-hook.js post:utterance-check utterance-check.js standard,strict
150
+ ```
151
+
152
+ ## Installing @kontourai/survey
153
+
154
+ The CLI adapter uses a dynamic import so flow-agents itself does not list `@kontourai/survey` as a dependency. Install it in the target workspace:
155
+
156
+ ```bash
157
+ npm install @kontourai/survey
158
+ ```
159
+
160
+ For model-backed extraction (production-quality, requires `@anthropic-ai/sdk`):
161
+
162
+ ```bash
163
+ npm install @kontourai/survey @anthropic-ai/sdk
164
+ ```
165
+
166
+ Then inject the Anthropic extractor by extending the CLI adapter or creating a wrapper script that calls `surveyAgentUtterance` with `createAnthropicUtteranceExtractor`.
167
+
168
+ ## Non-Goals
169
+
170
+ - Do not make `@kontourai/survey` a mandatory dependency of flow-agents.
171
+ - Do not copy Survey's extraction or inquiry schemas into flow-agents.
172
+ - Do not auto-register the hook in the default pack; it is opt-in only.
173
+ - Do not make the hook blocking without explicit `--strict` / `FLOW_AGENTS_UTTERANCE_CHECK_STRICT=true`.
174
+ - Do not silently decide anything. The hook injects guidance; the agent decides next steps.
175
+
176
+ ## Current Integration Shape
177
+
178
+ The integration delivers:
179
+
180
+ 1. `src/cli/utterance-check.ts` — TypeScript CLI adapter. Accepts utterance text, optional bundle path, and agent ID. Dynamically imports `@kontourai/survey`. Outputs a JSON badge report to stdout and human-readable guidance to stderr. Mirrors the `veritas-governance` adapter pattern.
181
+
182
+ 2. `scripts/hooks/utterance-check.js` — CJS hook script. PostToolUse/Stop, non-blocking by default. Reads agent output text from the hook event, invokes the CLI adapter when `FLOW_AGENTS_UTTERANCE_CHECK_ENABLED=true`, and injects badge guidance into the agent context. Always fails open.
183
+
184
+ The forward path (out of scope for this slice):
185
+
186
+ - Register the hook in a dedicated `survey` pack for opt-in activation.
187
+ - Support injecting the Anthropic extractor via `FLOW_AGENTS_UTTERANCE_CHECK_EXTRACTOR=anthropic`.
188
+ - Surface badge results as evidence sidecar entries (linking utterance coverage to workflow evidence).
189
+ - Auto-propose new claim mappings from unsupported statements via the Survey mapping proposer.
190
+
191
+ Survey source and API details: https://github.com/kontourai/survey
@@ -378,7 +378,7 @@ Completion gate:
378
378
 
379
379
  The validator and stop hook enforce this shape for terminal workflows. If a delivery is terminal and neither the Markdown artifact nor `state.json.artifact_paths` points at durable docs, validation should fail unless the artifact records an explicit no-docs decision.
380
380
 
381
- ## 10. Capture Learning
381
+ ## 11. Capture Learning
382
382
 
383
383
  Use `learning-review` after release, failed gates, incidents, repeated friction, or workflow gaps.
384
384