@kontourai/flow-agents 3.2.0 → 3.3.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.
Files changed (50) hide show
  1. package/.github/workflows/ci.yml +12 -0
  2. package/CHANGELOG.md +13 -0
  3. package/build/src/cli/assignment-provider.js +10 -1
  4. package/build/src/cli/workflow-artifact-cleanup-audit.js +418 -11
  5. package/build/src/cli/workflow-sidecar.d.ts +224 -0
  6. package/build/src/cli/workflow-sidecar.js +775 -4
  7. package/build/src/tools/validate-source-tree.js +3 -2
  8. package/context/contracts/artifact-contract.md +16 -2
  9. package/context/scripts/hooks/workflow-steering.js +73 -1
  10. package/docs/coordination-guide.md +370 -0
  11. package/docs/decisions/agent-coordination.md +26 -9
  12. package/docs/decisions/index.md +2 -2
  13. package/docs/decisions/trust-reconcile.md +42 -9
  14. package/docs/fixture-ownership.md +3 -2
  15. package/docs/index.md +4 -0
  16. package/docs/integrations/flow-agents-console.md +108 -0
  17. package/docs/integrations/index.md +4 -0
  18. package/docs/workflow-artifact-lifecycle.md +38 -1
  19. package/evals/ci/antigaming-suite.sh +1 -0
  20. package/evals/ci/run-baseline.sh +6 -0
  21. package/evals/fixtures/reconcile-preflight/disputed-critique-unsuperseded.json +48 -0
  22. package/evals/fixtures/reconcile-preflight/standalone-disputed-session-local.json +59 -0
  23. package/evals/integration/test_checkpoint_signing.sh +10 -2
  24. package/evals/integration/test_ci_actor_identity.sh +221 -0
  25. package/evals/integration/test_fixture_retirement_audit.sh +2 -2
  26. package/evals/integration/test_publish_delivery.sh +59 -2
  27. package/evals/integration/test_reconcile_preflight.sh +304 -0
  28. package/evals/integration/test_takeover_protocol.sh +340 -0
  29. package/evals/integration/test_trust_reconcile_negatives.sh +91 -0
  30. package/evals/integration/test_verify_hold.sh +910 -0
  31. package/evals/integration/test_veritas_governance_kit.sh +257 -0
  32. package/evals/integration/test_workflow_artifact_cleanup_audit.sh +575 -3
  33. package/evals/run.sh +8 -0
  34. package/kits/builder/skills/continue-work/SKILL.md +2 -0
  35. package/kits/builder/skills/deliver/SKILL.md +73 -0
  36. package/kits/builder/skills/pull-work/SKILL.md +12 -2
  37. package/kits/veritas-governance/docs/README.md +81 -3
  38. package/kits/veritas-governance/fixtures/exemption/approved.trust-bundle.json +74 -0
  39. package/kits/veritas-governance/fixtures/exemption/not-approved.trust-bundle.json +74 -0
  40. package/kits/veritas-governance/flows/exemption-issuance.flow.json +35 -0
  41. package/kits/veritas-governance/kit.json +5 -0
  42. package/package.json +1 -1
  43. package/scripts/ci/trust-reconcile.js +78 -253
  44. package/scripts/hooks/lib/actor-identity.js +82 -0
  45. package/scripts/hooks/workflow-steering.js +73 -1
  46. package/scripts/lib/reconcile-shape.js +381 -0
  47. package/src/cli/assignment-provider.ts +12 -1
  48. package/src/cli/workflow-artifact-cleanup-audit.ts +483 -10
  49. package/src/cli/workflow-sidecar.ts +866 -4
  50. package/src/tools/validate-source-tree.ts +3 -2
@@ -49,6 +49,8 @@ Before doing anything else, restore the item's durable record into context throu
49
49
 
50
50
  If no durable record exists for the item, record that gap and rely on the issue body plus merged PRs/commits as the authoritative history.
51
51
 
52
+ If the item was taken over from a stale incumbent (a `reclaimable` selection resumed via pull-work's **Takeover Protocol**, #294 / ADR 0021 §5), restoring the durable record IS the resumption: the deterministic slug points at the incumbent's existing `.kontourai/flow-agents/<slug>/`, and you continue the incumbent's branch (the `resume_branch` from `takeover-preflight`/the supersede output) — never a new branch, never a restarted plan. Takeover is resumption, not restart.
53
+
52
54
  ### 2. Determine the next undone slice
53
55
 
54
56
  From the issue body plus the merged PRs and commits referencing the issue, determine which slices have **landed** and which is the **next undone slice**.
@@ -247,6 +247,25 @@ After review, verification, evidence, and Goal Fit are clean for the same diff:
247
247
  npm run workflow:sidecar -- publish-delivery .kontourai/flow-agents/<slug>
248
248
  ```
249
249
 
250
+ **#356 — local reconcile-shape preflight.** `publish-delivery`/`record-release` now run a
251
+ local, pre-push **reconcile-shape preflight** on the session's `trust.bundle` before
252
+ copying anything into `delivery/`. It reuses the exact same claim-shape classification
253
+ `scripts/ci/trust-reconcile.js` enforces in CI (`scripts/lib/reconcile-shape.js`), so it
254
+ can never silently drift from what the required Trust Reconcile check actually does. If
255
+ the bundle is ADR-0020-invalid (e.g. a command-backed claim whose command isn't in the
256
+ reconcile manifest, an unwaived `assumed` claim, or an un-superseded disputed critique),
257
+ publish is **refused, fail-closed** — non-zero exit, a loud `REFUSING to publish` message
258
+ naming each invalid claim and its fix, and nothing is written to `delivery/`. This is
259
+ distinct from the existing fail-**soft** behavior when no `trust.bundle` exists yet at all
260
+ (still a silent no-op). When refused: fix the named claim (re-record evidence, add a
261
+ missing waiver, or supersede the disputed critique), then retry — do not attempt to push
262
+ past the refusal. You can also run the same check manually, any time before publish, to
263
+ catch a shape issue locally instead of discovering it minutes later in CI:
264
+
265
+ ```bash
266
+ npm run workflow:sidecar -- reconcile-preflight .kontourai/flow-agents/<slug>
267
+ ```
268
+
250
269
  **#379 — per-session delivery paths.** `publishDelivery()` writes to a PER-SESSION path
251
270
  `delivery/<slug>/trust.bundle` (+ `trust.checkpoint.json` companions), where `<slug>` is
252
271
  your session artifact dir's basename — NOT the old shared flat `delivery/trust.bundle`.
@@ -274,6 +293,60 @@ After review, verification, evidence, and Goal Fit are clean for the same diff:
274
293
  too — `git add -A delivery/` after the force-add. Do NOT hand-delete the flat
275
294
  `delivery/trust.bundle` in a delivery PR while other PRs may still seal to it.)
276
295
 
296
+ **#293 — verify-hold gate. HARD STOP.** Before committing/pushing/opening a PR/merging,
297
+ run the verify-hold check (it also runs automatically inside `publish-delivery` /
298
+ `record-release` / `advance-state --status delivered`, but run it explicitly here BEFORE
299
+ committing/pushing, since by the time `record-release` runs the branch may already be
300
+ pushed). **The command differs by this repo's configured assignment provider kind — a bare
301
+ `verify-hold <slug>` with no provider flag always defaults to `--assignment-provider
302
+ local-file` (`runVerifyHold`'s documented default), so on a `github`-provider repo it reads
303
+ no local claim record and silently resolves `free`/PASS regardless of the real GitHub hold
304
+ state. The local-file-only invocation below is NOT sufficient for a `github`-provider repo —
305
+ the github branch is MANDATORY for that provider kind:**
306
+
307
+ - **local-file provider** (this repo's configured assignment provider, from
308
+ `effective-assignment-provider-settings`, is `local-file`):
309
+
310
+ ```bash
311
+ npm run workflow:sidecar -- verify-hold .kontourai/flow-agents/<slug>
312
+ ```
313
+
314
+ - **github provider**: render-then-execute, mirroring `pull-work`'s SKILL.md claim-side
315
+ pattern for the same ADR 0021 §1 join — first read the effective state (no live `gh` call
316
+ happens inside `workflow-sidecar.ts`; the skill renders it here), then pass the rendered
317
+ `.effective` JSON into `verify-hold` via `--effective-state-json`:
318
+
319
+ ```bash
320
+ gh issue view <issue-number> --json assignees,labels,comments > /tmp/issue.json
321
+ npm run assignment-provider -- status \
322
+ --provider github \
323
+ --subject-id <slug> \
324
+ --issue-json /tmp/issue.json \
325
+ --liveness-stream <path-to-events.jsonl> \
326
+ --self-actor <actor> \
327
+ > /tmp/assignment-status.json
328
+ npm run workflow:sidecar -- verify-hold .kontourai/flow-agents/<slug> \
329
+ --assignment-provider github \
330
+ --effective-state-json /tmp/assignment-status.json
331
+ ```
332
+
333
+ (`/tmp/assignment-status.json`'s top-level shape is `{ role, provider, assignment,
334
+ effective }`; `verify-hold --effective-state-json` reads the `.effective` field, matching
335
+ `assignment-provider status`'s own output shape directly — no reshaping needed.)
336
+
337
+ This is the ONE point in the whole workflow that BLOCKS instead of warns (ADR 0021 §3). It
338
+ asks exactly one question: is this actor still the fresh, non-superseded holder of this
339
+ subject (or is the subject free/self-held)? **If the check reports not-fresh-holder (exit
340
+ non-zero, `ok:false` in the JSON result): DO NOT commit, push, open a PR, or merge.** This
341
+ is a different failure mode from the `publish-delivery`/reconcile-shape preflight paragraph
342
+ above — that one is about the trust *bundle's shape* being invalid; this one is about
343
+ *actor hold* — another actor holds a fresh claim on this subject, your own claim has gone
344
+ stale, or the subject is assigned to a human. Do not conflate the two "REFUSING to publish"
345
+ messages. When refused, follow the reconcile guidance (the CLI's own `guidance` field, or
346
+ verbatim): re-run `pull-work`/`pickup-probe` to discover the current holder and hand off
347
+ cleanly (`learning-review`/handoff), or, if a human confirms this session should resume
348
+ ownership, run `ensure-session --supersede-stale` before retrying.
349
+
277
350
  3. Commit the verified diff, including the force-added `delivery/<slug>/` trust artifacts.
278
351
  4. Push the branch.
279
352
 
@@ -167,14 +167,24 @@ Read the returned `.effective.effective_state` and `.effective.reason` and class
167
167
 
168
168
  1. `effective_state: "held"` with `reason: "self_is_holder"` ⇒ `mine`: hand to `### 2. Enforce WIP And Shepherding`'s existing personal-WIP logic; do not re-offer as new, do not exclude as held-by-other.
169
169
  2. else `effective_state: "held"` (`reason: "fresh_liveness_heartbeat"` or `"liveness_claim_present_assignment_lagging"`) ⇒ excluded from the ready set by default.
170
- 3. else `effective_state: "reclaimable"` ⇒ offered, flagged, with a warning; selecting it requires an explicit recorded opt-in (record in `reclaimable_override`, and/or `alignment_questions`), never a silent normal pick. This issue does not implement takeover — offering a `reclaimable` candidate, never auto-reclaiming it, is the correct scope boundary (Design Decision 2; full takeover protocol is ADR 0021 §5 / #294).
170
+ 3. else `effective_state: "reclaimable"` ⇒ offered, flagged, with a warning; selecting it requires an explicit recorded opt-in (record in `reclaimable_override`, and/or `alignment_questions`), never a silent normal pick. On selecting a `reclaimable` candidate, run the **Takeover Protocol** (#294, ADR 0021 §5) below — takeover is resumption, not restart: grace-beat, supersede, then continue the incumbent's branch. Never auto-reclaim without the recorded opt-in.
171
171
  4. else `effective_state: "human-held"` ⇒ surfaced, never auto-reclaimed (Design Decision 3 / ADR 0021 §6): record the assignee identity and idle duration (`effective.holder.assignee`, `effective.holder.idle_days`) in `alignment_questions` with a recommended answer (e.g. "assigned to `<assignee>`, idle `<idle_days>` days — reclaim?" recommending confirmation before proceeding), and select only on the user's explicit confirmation.
172
- 5. else `effective_state: "free"` ⇒ offered normally — except a `superseded` liveness row (no active assignment, no fresh liveness) is surfaced but never auto-selected (full takeover semantics are #294; this is an accepted gap, not silently ignored), exactly as before this join upgrade.
172
+ 5. else `effective_state: "free"` ⇒ offered normally — including a `superseded` liveness row (no active assignment, no fresh liveness): now select-able via the **Takeover Protocol** below once the reclaimable/opt-in gate is satisfied (#294 implements the takeover semantics previously deferred here).
173
173
 
174
174
  An explicit user instruction to proceed despite a `held` or `reclaimable` classification (`--force`, "take it anyway", equivalent) overrides the exclusion/opt-in requirement; the override and its stated reason must be recorded in the artifact (`liveness_preflight`, `reclaimable_override`, and/or `priority_rationale`). A `human-held` classification is never overridden by `--force` alone — only the user's explicit answer to the recorded `alignment_questions` entry authorizes selecting it.
175
175
 
176
176
  This preflight now computes the **full** ADR 0021 §1 `assignment ⋈ liveness` join (previously liveness-only, pending #290): the assignment dimension is `#290`'s `AssignmentProvider` `status()` (`context/contracts/assignment-provider-contract.md`), joined against the same liveness stream this preflight already reads.
177
177
 
178
+ #### Takeover Protocol (#294, ADR 0021 §5) — resumption, not restart
179
+
180
+ When a `reclaimable` (or `superseded`-liveness) candidate is selected WITH the recorded opt-in, take it over by resuming the incumbent's work — never by starting a parallel branch or replanning. This is render-don't-execute: the CLI computes the decision and emits the exact steps; you run them.
181
+
182
+ 1. **Preflight:** `npm run workflow:sidecar -- takeover-preflight .kontourai/flow-agents/<slug>`. It returns `{action, effective_state, holder, resume_branch, grace_seconds, next_steps}`. Only `action: "grace-then-supersede"` proceeds; `back-off` (incumbent live/revived) ⇒ STOP and reselect; `ask-first` (human-held) ⇒ do not proceed without the user's explicit answer.
183
+ 2. **Grace beat:** wait `grace_seconds` (one heartbeat interval), then **re-run `takeover-preflight`**. If it now returns `back-off`, the incumbent revived — concede and reselect (this is the AC2 race guard). Proceed only if it is still `grace-then-supersede`.
184
+ 3. **Supersede:** `npm run workflow:sidecar -- ensure-session … --supersede-stale`. It re-checks the state and REFUSES if the incumbent revived in the meantime (a live `held` is never superseded), records the audit trail ("superseded actor X, last seen T, resuming from trust bundle"), and prints `resumed_branch`.
185
+ 4. **Resume the incumbent's branch — never a new one:** `git fetch origin <resume_branch> && git checkout <resume_branch>` (the `resume_branch` from step 1/3). Re-enter the existing artifact dir (the deterministic slug points at the same `.kontourai/flow-agents/<slug>/`); restore the durable record via the resume surface (#153) and continue from `handoff.json`/plan — do NOT re-plan or restart.
186
+ 5. **Record** the takeover (superseded actor, `resume_branch`, grace outcome) in `reclaimable_override`. If the superseded incumbent later wakes, it is blocked at publish by the verify-hold gate (#293) — the takeover is authoritative.
187
+
178
188
  `liveness claim`/`status`/`whoami` read/write the local runtime liveness stream, never GitHub issue/label/assignee state — this is not a provider mutation, and the two-provider-writes-only invariant in `## Contract` is unchanged by this slice. `#290` adds the one narrow, audited durable assignment claim that pairs with this liveness emit — see "Assignment Claim On Selection" below.
179
189
 
180
190
  ### 2. Enforce WIP And Shepherding
@@ -1,8 +1,10 @@
1
1
  # Veritas Governance Kit
2
2
 
3
3
  Turns a repo's **Veritas-governed Repo Standards** into deterministic, agentless **gate
4
- evidence**. Slice 1 ships the thinnest useful surface: one flow, one gate, that gates a real
5
- `veritas readiness` verdict.
4
+ evidence**, and gives operators a documented, gated path to **issue** the human-approval
5
+ exemptions ADR 0022 §2/§3 lets `delivery/DECLARED` carry. Slice 1 shipped the thinnest useful
6
+ surface: one flow, one gate, that gates a real `veritas readiness` verdict. This slice adds a
7
+ second, agentless flow for exemption issuance.
6
8
 
7
9
  This kit **wraps** [`@kontourai/veritas`](https://www.npmjs.com/package/@kontourai/veritas) via
8
10
  CLI invocation plus a small kit-local trust.bundle adapter. It does **not** fork, vendor, or
@@ -16,6 +18,7 @@ only projects Veritas's own recorded verdict into the Flow trust.bundle vocabula
16
18
  | Flow | `flows/readiness-check.flow.json` | Single-gate agentless flow `readiness -> gate-check`. The gate requires a **verified** `software-readiness-verdict` trust.bundle claim. |
17
19
  | Adapter | `adapter/readiness-to-trust-bundle.mjs` | Projects a `veritas readiness --check evidence --working-tree` evidence report into a Hachure `trust.bundle` (via `@kontourai/surface`), deriving the claim status from Veritas's own blocking-failure signal. |
18
20
  | Fixtures | `fixtures/readiness/*.readiness-report.json` | Captured **real** Veritas readiness reports (a ready clean tree, and a not-ready tree with a required CLI artifact deleted) used by the eval. |
21
+ | Flow | `flows/exemption-issuance.flow.json` | Single-gate agentless flow `request -> human-approval-gate -> issue`. The gate requires a **verified** `no-agent-delivery-exemption-approval` trust.bundle claim (`subjectType: "delivery-scope"`) before the `issue` step's write is flow-sanctioned. Issues a `delivery/DECLARED` exemption entry per ADR 0022 §2/§3. |
19
22
 
20
23
  The gate uses provider-neutral Flow vocabulary (`kind: "trust.bundle"`, `bundle_claim`) — the
21
24
  same vocabulary `kits/builder/flows/build.flow.json` uses. Veritas is simply the producer that
@@ -42,6 +45,79 @@ flow evaluate readiness --gate gate-check-gate --exit-code
42
45
  # exit 0 when readiness is ready (claim verified); exit 1 (block) otherwise.
43
46
  ```
44
47
 
48
+ ## How to issue a no-agent-delivery exemption
49
+
50
+ `flows/exemption-issuance.flow.json` (ADR 0022 §3, "the kit issues, the anchor enforces") gives
51
+ an operator who needs to declare a `no-agent-delivery` exemption — e.g. dependabot,
52
+ release-please, or another non-agent actor class — a documented, gated path instead of
53
+ hand-writing `delivery/DECLARED` JSON blind. See `delivery/README.md` for how `delivery/`
54
+ itself is used by CI, and ADR 0022 §3 for why issuance/audit live in this kit while enforcement
55
+ stays anchor-side (`scripts/ci/trust-reconcile.js`, unmodified and unaware of this kit).
56
+
57
+ ```bash
58
+ # 1. A human approver authors a Hachure trust.bundle asserting the exemption approval.
59
+ # (No adapter script exists for this slice -- the bundle is hand-authored or produced
60
+ # by whatever approval tooling records the decision; see "Human-approval evidence: what
61
+ # is and is not enforced" below for why this is convention, not a structural human-only
62
+ # guarantee.)
63
+ # Minimal bundle shape: {schemaVersion, source, claims:[{claimType:
64
+ # "no-agent-delivery-exemption-approval", subjectType: "delivery-scope",
65
+ # status: "verified", ...}], evidence:[...], policies:[...], events:[...]}
66
+
67
+ # 2. Gate it (agentless, CI-callable).
68
+ flow init
69
+ flow start kits/veritas-governance/flows/exemption-issuance.flow.json --run-id exemption
70
+ flow attach-evidence exemption --gate human-approval-gate --file approval.bundle --bundle
71
+ flow evaluate exemption --gate human-approval-gate --exit-code
72
+ # exit 0 once the approval claim is verified; exit 1 (block) otherwise.
73
+
74
+ # 3. Once the gate passes, append the approved entry to delivery/DECLARED (append, do NOT
75
+ # overwrite an existing array -- see delivery/DECLARED's current 2-entry file on main).
76
+ # All four fields are required: scope, reason, approved_by, declared_at. Compound scope
77
+ # forms (space-separated, ANDed -- e.g. "author:github-actions[bot]
78
+ # branch-prefix:release-please--") are supported by the reconciler's scope matcher; see
79
+ # ADR 0022's compound-scope addendum.
80
+ ```
81
+
82
+ Example appended entry (third element of the existing `delivery/DECLARED` array — never a
83
+ replacement of it):
84
+
85
+ ```json
86
+ {
87
+ "scope": "author:some-bot[bot]",
88
+ "reason": "why this actor class needs the exemption",
89
+ "approved_by": "<human approver identity/decision reference>",
90
+ "declared_at": "<ISO 8601 timestamp>"
91
+ }
92
+ ```
93
+
94
+ ## Human-approval evidence: what is and is not enforced
95
+
96
+ The `human-approval-gate`'s `expects[]` entry only requires a **verified** trust.bundle claim
97
+ of the right `claimType` (`no-agent-delivery-exemption-approval`) and `subjectType`
98
+ (`delivery-scope`). **Flow's schema and CLI do not distinguish a human-authored bundle from an
99
+ agent-authored one** — `trust-bundle.schema.json`'s `source` and `producerId` fields are
100
+ free-text, with no enum, no cryptographic binding, and no CLI-side identity check.
101
+ "Human-attached" is an **operating convention** this flow's `description`/`explore_hint` text
102
+ encode (the gate's own copy tells an operator this evidence is meant to be authored by a human
103
+ approver out-of-band), not a mechanism the gate itself enforces. Anyone who can run `flow
104
+ attach-evidence --bundle` with a conforming bundle can satisfy this gate, exactly as anyone with
105
+ commit access could already hand-author `delivery/DECLARED` directly.
106
+
107
+ This is the same class of residual ADR 0022 already carries honestly for the marker file
108
+ itself: `approved_by` on `delivery/DECLARED` is free text, not bound to an authenticated
109
+ identity, mitigated by the loud, un-suppressible DECLARED line plus CODEOWNERS review on
110
+ `/delivery/DECLARED` — not by identity attestation. This flow adds **guidance and an audit
111
+ trail** (a named gate, a named claim type, a documented sequence) on top of that same
112
+ mitigation, not a new authentication boundary. Structural producer authentication — binding
113
+ gate satisfaction to an authenticated producer identity, rather than to a schema-valid claim
114
+ attached by anyone with CLI access — is upstream **Flow trusted-producer** work
115
+ (`docs/operating-layers.md`, `docs/flow-kit-repository-contract.md` in this repo describe the
116
+ config surface; the config itself is Flow-core, tracked at #225/#293-family), not something
117
+ this kit's `.flow.json` can itself express. Do not read a passing `human-approval-gate` as a
118
+ structural guarantee that a human attached the evidence — read it as "a verified claim of the
119
+ right shape was attached," full stop.
120
+
45
121
  ## Semantics
46
122
 
47
123
  **Settled** (owner-ratified + investigation-confirmed; see
@@ -72,4 +148,6 @@ decision deferred to a later slice (see the WS5 shaping's open decisions).
72
148
 
73
149
  Skills (`consult-standards`, `governance-evidence`), the fuller `merge-readiness` flow, the
74
150
  `standards-authoring` flow, and the `knowledge` dependency are later slices — see the WS5
75
- backlog.
151
+ backlog. The `exemption-usage-review` periodic audit flow/skill named in ADR 0022 §3 (walks
152
+ `delivery/DECLARED` history and surfaces standing exemptions for owner re-confirmation —
153
+ process visibility, not enforcement) is also a separate, later slice, not shipped here.
@@ -0,0 +1,74 @@
1
+ {
2
+ "schemaVersion": 5,
3
+ "source": "veritas-governance-kit/exemption-fixture",
4
+ "claims": [
5
+ {
6
+ "id": "exemption-fixture.no-agent-delivery-exemption-approval.author-test-bot",
7
+ "subjectType": "delivery-scope",
8
+ "subjectId": "author:test-bot[bot]",
9
+ "facet": "veritas-governance.exemption",
10
+ "claimType": "no-agent-delivery-exemption-approval",
11
+ "fieldOrBehavior": "exemptionApproval",
12
+ "value": {
13
+ "scope": "author:test-bot[bot]",
14
+ "reason": "test-bot automation PR; no agent delivery involved",
15
+ "approved_by": "eval-fixture-approver"
16
+ },
17
+ "createdAt": "2026-07-01T00:00:00Z",
18
+ "updatedAt": "2026-07-01T00:00:00Z",
19
+ "impactLevel": "high",
20
+ "verificationPolicyId": "policy:no-agent-delivery-exemption-approval",
21
+ "metadata": {
22
+ "producer": "human-approver",
23
+ "source": "exemption-issuance-fixture"
24
+ },
25
+ "status": "verified"
26
+ }
27
+ ],
28
+ "evidence": [
29
+ {
30
+ "id": "ev:exemption-fixture.no-agent-delivery-exemption-approval.author-test-bot",
31
+ "claimId": "exemption-fixture.no-agent-delivery-exemption-approval.author-test-bot",
32
+ "evidenceType": "policy_rule",
33
+ "method": "auditability",
34
+ "sourceRef": "human-approver:exemption-issuance-fixture",
35
+ "excerptOrSummary": "A human maintainer approved a no-agent-delivery exemption for scope author:test-bot[bot].",
36
+ "observedAt": "2026-07-01T00:00:00Z",
37
+ "collectedBy": "veritas-governance-kit/exemption-fixture",
38
+ "passing": true
39
+ }
40
+ ],
41
+ "events": [
42
+ {
43
+ "id": "evt:exemption-fixture.no-agent-delivery-exemption-approval.author-test-bot",
44
+ "claimId": "exemption-fixture.no-agent-delivery-exemption-approval.author-test-bot",
45
+ "status": "verified",
46
+ "actor": "veritas-governance-kit/exemption-fixture",
47
+ "method": "auditability",
48
+ "evidenceIds": [
49
+ "ev:exemption-fixture.no-agent-delivery-exemption-approval.author-test-bot"
50
+ ],
51
+ "createdAt": "2026-07-01T00:00:00Z",
52
+ "verifiedAt": "2026-07-01T00:00:00Z"
53
+ }
54
+ ],
55
+ "policies": [
56
+ {
57
+ "id": "policy:no-agent-delivery-exemption-approval",
58
+ "claimType": "no-agent-delivery-exemption-approval",
59
+ "requiredEvidence": [
60
+ "policy_rule"
61
+ ],
62
+ "acceptanceCriteria": [
63
+ "A human maintainer has approved this delivery-scope exemption from Trust Reconcile's bundle-required enforcement."
64
+ ],
65
+ "reviewAuthority": "human",
66
+ "validityRule": {
67
+ "kind": "manual"
68
+ },
69
+ "stalenessTriggers": [],
70
+ "conflictRules": [],
71
+ "impactLevel": "high"
72
+ }
73
+ ]
74
+ }
@@ -0,0 +1,74 @@
1
+ {
2
+ "schemaVersion": 5,
3
+ "source": "veritas-governance-kit/exemption-fixture",
4
+ "claims": [
5
+ {
6
+ "id": "exemption-fixture.no-agent-delivery-exemption-approval.author-test-bot",
7
+ "subjectType": "delivery-scope",
8
+ "subjectId": "author:test-bot[bot]",
9
+ "facet": "veritas-governance.exemption",
10
+ "claimType": "no-agent-delivery-exemption-approval",
11
+ "fieldOrBehavior": "exemptionApproval",
12
+ "value": {
13
+ "scope": "author:test-bot[bot]",
14
+ "reason": "test-bot automation PR; no agent delivery involved",
15
+ "approved_by": "eval-fixture-approver"
16
+ },
17
+ "createdAt": "2026-07-01T00:00:00Z",
18
+ "updatedAt": "2026-07-01T00:00:00Z",
19
+ "impactLevel": "high",
20
+ "verificationPolicyId": "policy:no-agent-delivery-exemption-approval",
21
+ "metadata": {
22
+ "producer": "human-approver",
23
+ "source": "exemption-issuance-fixture"
24
+ },
25
+ "status": "disputed"
26
+ }
27
+ ],
28
+ "evidence": [
29
+ {
30
+ "id": "ev:exemption-fixture.no-agent-delivery-exemption-approval.author-test-bot",
31
+ "claimId": "exemption-fixture.no-agent-delivery-exemption-approval.author-test-bot",
32
+ "evidenceType": "policy_rule",
33
+ "method": "auditability",
34
+ "sourceRef": "human-approver:exemption-issuance-fixture",
35
+ "excerptOrSummary": "A no-agent-delivery exemption approval claim was attached but is not (yet) verified for scope author:test-bot[bot].",
36
+ "observedAt": "2026-07-01T00:00:00Z",
37
+ "collectedBy": "veritas-governance-kit/exemption-fixture",
38
+ "passing": false
39
+ }
40
+ ],
41
+ "events": [
42
+ {
43
+ "id": "evt:exemption-fixture.no-agent-delivery-exemption-approval.author-test-bot",
44
+ "claimId": "exemption-fixture.no-agent-delivery-exemption-approval.author-test-bot",
45
+ "status": "disputed",
46
+ "actor": "veritas-governance-kit/exemption-fixture",
47
+ "method": "auditability",
48
+ "evidenceIds": [
49
+ "ev:exemption-fixture.no-agent-delivery-exemption-approval.author-test-bot"
50
+ ],
51
+ "createdAt": "2026-07-01T00:00:00Z",
52
+ "verifiedAt": "2026-07-01T00:00:00Z"
53
+ }
54
+ ],
55
+ "policies": [
56
+ {
57
+ "id": "policy:no-agent-delivery-exemption-approval",
58
+ "claimType": "no-agent-delivery-exemption-approval",
59
+ "requiredEvidence": [
60
+ "policy_rule"
61
+ ],
62
+ "acceptanceCriteria": [
63
+ "A human maintainer has approved this delivery-scope exemption from Trust Reconcile's bundle-required enforcement."
64
+ ],
65
+ "reviewAuthority": "human",
66
+ "validityRule": {
67
+ "kind": "manual"
68
+ },
69
+ "stalenessTriggers": [],
70
+ "conflictRules": [],
71
+ "impactLevel": "high"
72
+ }
73
+ ]
74
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "id": "veritas-governance.exemption-issuance",
3
+ "version": "1.0",
4
+ "steps": [
5
+ { "id": "request", "next": "issue" },
6
+ { "id": "issue", "next": null }
7
+ ],
8
+ "gates": {
9
+ "human-approval-gate": {
10
+ "step": "issue",
11
+ "expects": [
12
+ {
13
+ "id": "exemption-approval",
14
+ "kind": "trust.bundle",
15
+ "required": true,
16
+ "description": "A human maintainer has approved this delivery-scope exemption from Trust Reconcile's bundle-required enforcement (ADR 0022 §1/§2), recorded as a verified no-agent-delivery-exemption-approval trust.bundle claim.",
17
+ "explore_hint": "A human approver authors a Hachure trust.bundle carrying a no-agent-delivery-exemption-approval / delivery-scope claim with status verified, then `flow attach-evidence <run> --gate human-approval-gate --file <bundle> --bundle`.",
18
+ "bundle_claim": {
19
+ "claimType": "no-agent-delivery-exemption-approval",
20
+ "subjectType": "delivery-scope",
21
+ "accepted_statuses": ["verified"]
22
+ }
23
+ }
24
+ ],
25
+ "on_route_back": {
26
+ "missing_evidence": "issue",
27
+ "default": "issue"
28
+ },
29
+ "route_back_policy": {
30
+ "max_attempts": 3,
31
+ "on_exceeded": "block"
32
+ }
33
+ }
34
+ }
35
+ }
@@ -8,6 +8,11 @@
8
8
  "id": "veritas-governance.readiness-check",
9
9
  "path": "flows/readiness-check.flow.json",
10
10
  "description": "Single-gate agentless flow: requires a verified software-readiness-verdict trust.bundle claim (projected from `veritas readiness --check evidence --working-tree`) before the gate-check step can pass. CI-callable, K0."
11
+ },
12
+ {
13
+ "id": "veritas-governance.exemption-issuance",
14
+ "path": "flows/exemption-issuance.flow.json",
15
+ "description": "Agentless K0 flow issuing a delivery/DECLARED no-agent-delivery exemption (ADR 0022 §2/§3): step request -> gate human-approval-gate (requires a verified no-agent-delivery-exemption-approval trust.bundle claim, satisfiable only by a human-authored approval bundle by convention -- see docs/README.md) -> step issue, which appends the approved entry to delivery/DECLARED. CI-callable."
11
16
  }
12
17
  ],
13
18
  "docs": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kontourai/flow-agents",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "Flow Agents — a Kontour product that applies Flow and Veritas discipline as a portable process layer inside the agent tools you already use: Claude Code, Codex, Kiro, opencode, pi, and GitHub Actions — with framework adapters (AWS Strands preview) on the same policy-engine contract.",
5
5
  "keywords": [
6
6
  "agents",