@kontourai/flow-agents 2.2.0 → 2.4.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/CODEOWNERS +8 -0
- package/.github/workflows/ci.yml +32 -0
- package/AGENTS.md +4 -4
- package/CHANGELOG.md +46 -0
- package/CONTEXT.md +14 -0
- package/README.md +9 -3
- package/agents/dev.json +1 -1
- package/agents/tool-code-reviewer.json +1 -1
- package/agents/tool-planner.json +3 -3
- package/agents/tool-verifier.json +3 -3
- package/build/src/cli/console-learning-projection.js +3 -2
- package/build/src/cli/init.js +104 -21
- package/build/src/cli/kit.js +37 -6
- package/build/src/cli/pull-work-provider.js +1 -1
- package/build/src/cli/usage-feedback.js +3 -3
- package/build/src/cli/validate-hook-influence.js +1 -0
- package/build/src/cli/validate-workflow-artifacts.js +22 -6
- package/build/src/cli/workflow-artifact-cleanup-audit.js +36 -2
- package/build/src/cli/workflow-sidecar.d.ts +14 -7
- package/build/src/cli/workflow-sidecar.js +792 -69
- package/build/src/flow-kit/validate.d.ts +23 -0
- package/build/src/flow-kit/validate.js +67 -1
- package/build/src/index.d.ts +1 -1
- package/build/src/index.js +1 -1
- package/build/src/lib/flow-resolver.d.ts +6 -4
- package/build/src/lib/flow-resolver.js +125 -58
- package/build/src/lib/local-artifact-root.d.ts +14 -2
- package/build/src/lib/local-artifact-root.js +22 -5
- package/build/src/lib/workflow-learning-projection.js +2 -2
- package/build/src/runtime-adapters.d.ts +12 -0
- package/build/src/runtime-adapters.js +56 -16
- package/build/src/tools/build-universal-bundles.js +49 -16
- package/build/src/tools/generate-context-map.js +10 -8
- package/build/src/tools/validate-source-tree.js +23 -1
- package/console.telemetry.json +22 -0
- package/context/contracts/artifact-contract.md +38 -7
- package/context/contracts/builder-kit-workflow-state-contract.md +3 -2
- package/context/contracts/decision-registry-contract.md +263 -0
- package/context/contracts/delivery-contract.md +1 -1
- package/context/contracts/planning-contract.md +2 -1
- package/context/contracts/review-contract.md +5 -3
- package/context/contracts/verification-contract.md +9 -1
- package/context/contracts/work-item-contract.md +1 -1
- package/context/deferred/parallelization.md +1 -1
- package/context/gate-awareness.md +4 -4
- package/context/scripts/git-status.sh +2 -2
- package/context/scripts/hooks/config-protection.js +502 -2
- package/context/scripts/hooks/lib/config-protection-remedies.js +69 -0
- package/context/scripts/hooks/run-hook.js +14 -1
- package/context/scripts/hooks/stop-goal-fit.js +1140 -99
- package/context/scripts/hooks/workflow-steering.js +212 -6
- package/docs/adr/0007-flow-skill-kit-tool-boundary.md +2 -0
- package/docs/adr/0015-flow-flow-agents-boundary-reconciliation.md +35 -0
- package/docs/adr/0019-kit-dependency-ownership.md +62 -0
- package/docs/adr/0020-trust-reconcile-manifest-and-claim-classification.md +290 -0
- package/docs/adr/0021-assignment-leases-and-stale-claim-takeover.md +221 -0
- package/docs/adr/0022-fail-closed-delivery-reconciliation-with-governed-exemptions.md +283 -0
- package/docs/agent-system-guidebook.md +3 -3
- package/docs/agent-usage-feedback-loop.md +6 -6
- package/docs/context-map.md +9 -7
- package/docs/decisions/decision-records.md +57 -0
- package/docs/decisions/index.md +14 -0
- package/docs/decisions/promotion-gate.md +52 -0
- package/docs/developer-architecture.md +1 -1
- package/docs/fixture-ownership.md +3 -0
- package/docs/flow-kit-repository-contract.md +5 -5
- package/docs/getting-started.md +12 -2
- package/docs/integrations/harness-install.md +2 -1
- package/docs/kit-authoring-guide.md +64 -5
- package/docs/knowledge-kit.md +5 -1
- package/docs/learnings/2026-07-improvement-program.md +203 -0
- package/docs/migrations.md +6 -5
- package/docs/north-star.md +2 -2
- package/docs/operating-layers.md +4 -3
- package/docs/repository-structure.md +5 -5
- package/docs/skills-map.md +8 -8
- package/docs/spec/runtime-hook-surface.md +19 -15
- package/docs/spikes/graph-provider-2026-07.md +155 -0
- package/docs/standards-register.md +7 -7
- package/docs/trust-anchor-adoption.md +105 -4
- package/docs/work-item-adapters.md +1 -1
- package/docs/workflow-artifact-lifecycle.md +72 -9
- package/docs/workflow-eval-strategy.md +3 -3
- package/docs/workflow-shared-contracts.md +1 -1
- package/docs/workflow-usage-guide.md +254 -21
- package/evals/acceptance/DEMO-false-completion.md +20 -11
- package/evals/acceptance/prove-capture-teeth-declared.sh +15 -15
- package/evals/acceptance/prove-capture-teeth.sh +11 -11
- package/evals/acceptance/test_kiro_harness.sh +1 -1
- package/evals/ci/antigaming-suite.sh +5 -0
- package/evals/ci/run-baseline.sh +65 -1
- package/evals/fixtures/flow-kit-repository/invalid-bad-dependency/flows/review.flow.json +26 -0
- package/evals/fixtures/flow-kit-repository/invalid-bad-dependency/kit.json +13 -0
- package/evals/fixtures/flow-kit-repository/valid-with-dependency/flows/review.flow.json +26 -0
- package/evals/fixtures/flow-kit-repository/valid-with-dependency/kit.json +13 -0
- package/evals/fixtures/hook-influence/cases.json +32 -0
- package/evals/fixtures/pull-work-provider/github-issues.json +6 -6
- package/evals/fixtures/trust-reconcile-exploits/fabricated-attestation.json +59 -0
- package/evals/fixtures/trust-reconcile-exploits/no-label-bypass.json +36 -0
- package/evals/fixtures/trust-reconcile-exploits/skip-assumed-bypass.json +59 -0
- package/evals/fixtures/trust-reconcile-exploits/status-misassertion.json +48 -0
- package/evals/fixtures/trust-reconcile-exploits/waived-command-check.json +44 -0
- package/evals/fixtures/trust-reconcile-mixed-bundle/mixed-bundle.json +159 -0
- package/evals/fixtures/trust-reconcile-ws3/ws3-bundle.json +920 -0
- package/evals/integration/test_actor_identity.sh +254 -0
- package/evals/integration/test_builder_step_producers.sh +33 -23
- package/evals/integration/test_bundle_install.sh +22 -16
- package/evals/integration/test_bundle_lifecycle.sh +11 -11
- package/evals/integration/test_captured_fail_reconciliation.sh +50 -50
- package/evals/integration/test_checkpoint_signing.sh +43 -0
- package/evals/integration/test_claim_lookup.sh +4 -4
- package/evals/integration/test_codex_hook_resolution.sh +114 -0
- package/evals/integration/test_command_log_concurrency.sh +8 -8
- package/evals/integration/test_command_log_fork_classification.sh +3 -3
- package/evals/integration/test_command_log_integrity.sh +16 -16
- package/evals/integration/test_console_learning_projection.sh +1 -1
- package/evals/integration/test_dual_emit_flow_step.sh +145 -0
- package/evals/integration/test_enforcer_expects_driven.sh +12 -12
- package/evals/integration/test_evidence_capture_hook.sh +14 -13
- package/evals/integration/test_fixture_retirement_audit.sh +2 -2
- package/evals/integration/test_flow_agents_statusline.sh +2 -2
- package/evals/integration/test_flow_kit_install_git.sh +52 -0
- package/evals/integration/test_flow_kit_repository.sh +2 -0
- package/evals/integration/test_flowdef_session_activation.sh +6 -6
- package/evals/integration/test_flowdef_union_floor_regression.sh +429 -0
- package/evals/integration/test_gate_bypass_chain.sh +52 -40
- package/evals/integration/test_gate_lockdown.sh +97 -73
- package/evals/integration/test_gate_review_inquiry_records.sh +3 -3
- package/evals/integration/test_goal_fit_escape_hatch.sh +10 -10
- package/evals/integration/test_goal_fit_ghost_session.sh +104 -0
- package/evals/integration/test_goal_fit_hook.sh +32 -32
- package/evals/integration/test_goal_fit_rederive.sh +9 -9
- package/evals/integration/test_hook_category_behaviors.sh +103 -0
- package/evals/integration/test_hook_influence_cases.sh +1 -0
- package/evals/integration/test_install_merge.sh +262 -1
- package/evals/integration/test_kit_identity_trust.sh +6 -6
- package/evals/integration/test_liveness_conflict_injection.sh +587 -0
- package/evals/integration/test_liveness_heartbeat.sh +677 -0
- package/evals/integration/test_liveness_verdict.sh +394 -0
- package/evals/integration/test_local_flow_kit_install.sh +15 -0
- package/evals/integration/test_phase_map_and_gate_claim.sh +63 -11
- package/evals/integration/test_promote_gate.sh +178 -0
- package/evals/integration/test_publish_delivery.sh +2 -2
- package/evals/integration/test_pull_work_liveness_preflight.sh +386 -0
- package/evals/integration/test_pull_work_provider.sh +2 -2
- package/evals/integration/test_reconcile_soundness.sh +4 -4
- package/evals/integration/test_resolvefirststep_security.sh +22 -0
- package/evals/integration/test_runtime_adapter_activation.sh +87 -18
- package/evals/integration/test_session_resume_roundtrip.sh +147 -0
- package/evals/integration/test_sidecar_field_preservation.sh +249 -0
- package/evals/integration/test_trust_reconcile.sh +2 -2
- package/evals/integration/test_trust_reconcile_manifest.sh +79 -0
- package/evals/integration/test_trust_reconcile_mixed_bundle.sh +96 -0
- package/evals/integration/test_trust_reconcile_negatives.sh +151 -0
- package/evals/integration/test_usage_feedback_global.sh +5 -5
- package/evals/integration/test_validate_artifacts_portability.sh +60 -0
- package/evals/integration/test_verify_cli.sh +2 -2
- package/evals/integration/test_veritas_governance_kit.sh +117 -0
- package/evals/integration/test_workflow_artifact_cleanup_audit.sh +26 -1
- package/evals/integration/test_workflow_artifacts.sh +33 -0
- package/evals/integration/test_workflow_sidecar_writer.sh +723 -74
- package/evals/integration/test_workflow_steering_hook.sh +175 -5
- package/evals/lib/codex-provider.sh +1 -1
- package/evals/lib/node.sh +19 -1
- package/evals/run.sh +22 -0
- package/evals/static/test_decisions.sh +150 -0
- package/evals/static/test_flowdef_codeowners_coverage.sh +56 -0
- package/evals/static/test_package.sh +19 -10
- package/evals/static/test_universal_bundles.sh +48 -3
- package/evals/static/test_workflow_skills.sh +41 -8
- package/kits/builder/flows/build.flow.json +3 -74
- package/kits/builder/flows/publish-learn.flow.json +90 -0
- package/kits/builder/kit.json +11 -0
- package/kits/builder/skills/builder-shape/SKILL.md +1 -1
- package/kits/builder/skills/deliver/SKILL.md +13 -11
- package/kits/builder/skills/design-probe/SKILL.md +4 -4
- package/kits/builder/skills/evidence-gate/SKILL.md +26 -1
- package/kits/builder/skills/execute-plan/SKILL.md +2 -2
- package/kits/builder/skills/fix-bug/SKILL.md +2 -0
- package/kits/builder/skills/gate-review/SKILL.md +6 -6
- package/kits/builder/skills/idea-to-backlog/SKILL.md +1 -1
- package/kits/builder/skills/learning-review/SKILL.md +7 -7
- package/kits/builder/skills/pickup-probe/SKILL.md +5 -4
- package/kits/builder/skills/plan-work/SKILL.md +27 -5
- package/kits/builder/skills/pull-work/SKILL.md +80 -5
- package/kits/builder/skills/release-readiness/SKILL.md +4 -4
- package/kits/builder/skills/review-work/SKILL.md +24 -1
- package/kits/builder/skills/tdd-workflow/SKILL.md +2 -0
- package/kits/builder/skills/verify-work/SKILL.md +8 -1
- package/kits/catalog.json +6 -0
- package/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +178 -0
- package/kits/veritas-governance/docs/README.md +75 -0
- package/kits/veritas-governance/fixtures/readiness/not-ready.readiness-report.json +4645 -0
- package/kits/veritas-governance/fixtures/readiness/ready.readiness-report.json +4403 -0
- package/kits/veritas-governance/flows/readiness-check.flow.json +35 -0
- package/kits/veritas-governance/kit.json +16 -0
- package/package.json +8 -4
- package/packaging/README.md +2 -2
- package/packaging/conformance/fixtures/config-protection--allow-read-state-json.json +20 -0
- package/packaging/conformance/fixtures/config-protection--block-write-state-json.json +20 -0
- package/packaging/conformance/fixtures/stop-goal-fit--block-bundle-disputed-claim.json +1 -1
- package/packaging/conformance/fixtures/stop-goal-fit--block-capture-contradicts-claimed-pass.json +1 -1
- package/packaging/manifest.json +9 -10
- package/schemas/decision-record.schema.json +109 -0
- package/schemas/workflow-evidence.schema.json +1 -1
- package/schemas/workflow-state.schema.json +5 -0
- package/scripts/README.md +8 -3
- package/scripts/check-content-boundary.cjs +1 -1
- package/scripts/check-decisions.cjs +356 -0
- package/scripts/ci/derive-claim-status.mjs +74 -0
- package/scripts/ci/trust-reconcile.js +436 -79
- package/scripts/git-status.sh +2 -2
- package/scripts/hooks/claude-telemetry-hook.js +37 -3
- package/scripts/hooks/codex-telemetry-hook.js +36 -2
- package/scripts/hooks/config-protection.js +102 -30
- package/scripts/hooks/evidence-capture.js +3 -3
- package/scripts/hooks/lib/actor-identity.js +368 -0
- package/scripts/hooks/lib/config-protection-remedies.js +69 -0
- package/scripts/hooks/lib/liveness-heartbeat.js +361 -0
- package/scripts/hooks/lib/liveness-policy.js +127 -0
- package/scripts/hooks/lib/liveness-read.js +105 -12
- package/scripts/hooks/lib/liveness-write.js +46 -0
- package/scripts/hooks/lib/local-artifact-paths.js +12 -6
- package/scripts/hooks/opencode-telemetry-hook.js +27 -1
- package/scripts/hooks/pi-telemetry-hook.js +27 -1
- package/scripts/hooks/stop-goal-fit.js +157 -26
- package/scripts/hooks/workflow-steering.js +77 -3
- package/scripts/install-codex-home.sh +138 -38
- package/scripts/statusline/flow-agents-statusline.js +2 -2
- package/src/cli/console-learning-projection.ts +3 -2
- package/src/cli/init.ts +101 -21
- package/src/cli/kit.ts +37 -6
- package/src/cli/public-api.test.mjs +58 -6
- package/src/cli/pull-work-provider.ts +1 -1
- package/src/cli/trust-bundle-policy-order.test.mjs +87 -0
- package/src/cli/usage-feedback.ts +3 -3
- package/src/cli/validate-hook-influence.ts +1 -0
- package/src/cli/validate-workflow-artifacts.ts +22 -6
- package/src/cli/veritas-readiness-adapter.test.mjs +267 -0
- package/src/cli/workflow-artifact-cleanup-audit.ts +35 -2
- package/src/cli/workflow-sidecar.ts +795 -71
- package/src/flow-kit/validate.ts +74 -1
- package/src/index.ts +6 -2
- package/src/lib/flow-resolver.ts +123 -55
- package/src/lib/local-artifact-root.ts +24 -5
- package/src/lib/workflow-learning-projection.ts +2 -2
- package/src/runtime-adapters.ts +61 -15
- package/src/tools/build-universal-bundles.ts +49 -16
- package/src/tools/generate-context-map.ts +10 -8
- package/src/tools/validate-source-tree.ts +23 -1
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# SPIKE findings — graph database provider experience: Neo4j Community vs Kuzu (embedded)
|
|
2
|
+
|
|
3
|
+
- Issue: kontourai/flow-agents#318
|
|
4
|
+
- Executed: 2026-07-03 (agent session)
|
|
5
|
+
- **Graph snapshot timestamp: `2026-07-03T05:14:42Z`** (point-in-time; two builds in flight during the spike — #312 flow-agents, #314 traverse — so backlog edges may have moved since)
|
|
6
|
+
- Provider interface (#317) had NOT landed → used a throwaway extractor (`build-graph.js`) over the real stores, per scope.
|
|
7
|
+
- Engines exercised: **BOTH** — Neo4j Community 5 (Docker) AND Kuzu 0.11.3 (embedded, in-process via npm). All 5 canonical queries ran on both.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. Node / edge counts (identical on both engines)
|
|
12
|
+
|
|
13
|
+
**Nodes: 200**
|
|
14
|
+
|
|
15
|
+
| Label | Count | Source |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| Issue | 116 | flow-agents (112) + traverse (4), via `gh issue list --json` |
|
|
18
|
+
| Session | 40 | `.kontourai/flow-agents/archive/sweep-2026-07-02.json` (`archived[]`) |
|
|
19
|
+
| Decision | 23 | `docs/adr/*.md` (the *living* `docs/decisions/` registry from #310 does not exist yet — ADRs are the current decision records) |
|
|
20
|
+
| PR | 13 | flow-agents PRs that carry `closingIssuesReferences` |
|
|
21
|
+
| Learning | 8 | numbered sections of `docs/learnings/2026-07-improvement-program.md` |
|
|
22
|
+
|
|
23
|
+
**Edges: 227**
|
|
24
|
+
|
|
25
|
+
| Type | Count | Derivation |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| RELATES | 141 | prose `#NNN` cross-references (+ cross-repo `traverse#NN`, + ADR-0007 number collision) |
|
|
28
|
+
| MENTIONS | 35 | Decision→Issue and Learning→Issue `#NNN` references in doc bodies |
|
|
29
|
+
| BLOCKED_BY | 27 | metadata markers (`work-item-metadata.blockers[]`) AND prose ("blocked by/depends on #N") |
|
|
30
|
+
| CLOSES | 14 | PR→Issue from `closingIssuesReferences` |
|
|
31
|
+
| EVIDENCE_OF | 10 | Session→Decision/Issue — **heuristic** slug/title token overlap (≥2 shared ≥5-char tokens), flagged `heuristic:true` |
|
|
32
|
+
|
|
33
|
+
AC1 satisfied: both engines loaded the real graph; counts reported.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 2. Engine setup friction
|
|
38
|
+
|
|
39
|
+
### Neo4j Community (Docker)
|
|
40
|
+
- `docker run -d -p 7474:7474 -p 7687:7687 -e NEO4J_AUTH=neo4j/… neo4j:5-community` — image pull + boot to "Started" in ~30s. Zero config.
|
|
41
|
+
- **Schema-free load**: no DDL. `UNWIND $rows AS r CREATE (n:Label) SET n=r` for nodes; `UNWIND … MATCH (a{id}),(b{id}) CREATE (a)-[x:TYPE]->(b) SET x=r.props` for edges. Endpoints matched by `id` regardless of label — polyglot property bags "just work."
|
|
42
|
+
- Bulk load of 200 nodes + 227 edges via batched UNWIND: **~1.8s**.
|
|
43
|
+
- Ops cost: a running server + two ports + auth. Fine locally; a real dependency in CI/prod.
|
|
44
|
+
|
|
45
|
+
### Kuzu (embedded, npm)
|
|
46
|
+
- `npm install kuzu` → `new kuzu.Database(path)` + `new kuzu.Connection(db)`. In-process, no server, no ports. SQLite-for-graphs as advertised.
|
|
47
|
+
- **Typed schema REQUIRED up front**: `CREATE NODE TABLE Issue(id STRING PRIMARY KEY, …)` and `CREATE REL TABLE BLOCKED_BY(FROM Issue TO Issue, …)`. Multi-pair rel tables (`FROM Decision TO Issue, FROM Learning TO Issue`) are supported and needed here. This is more rigor than Neo4j but also more friction for an evolving/heterogeneous graph.
|
|
48
|
+
- **Escaping gotcha**: string literals with `'` fail the Cypher parser even with SQL-style `''` doubling — had to switch to parameterized `conn.prepare()`/`conn.execute()`. (Real backlog titles contain apostrophes, em-dashes, emoji — this bit immediately.)
|
|
49
|
+
- **Cleanup gotcha**: the DB is a file *plus* a `.wal` sidecar. Deleting only the file leaves a stale catalog → "Issue already exists in catalog" on reload. Must remove `<db>` and `<db>.wal`.
|
|
50
|
+
- Load of the same graph via per-row prepared statements: **~3.3s** (Kuzu's real strength is bulk `COPY FROM`, which I didn't use for 200 rows).
|
|
51
|
+
|
|
52
|
+
### ⚠️ Material viability finding (dominates the recommendation)
|
|
53
|
+
**Kuzu is abandoned upstream.** The npm package (`kuzu@0.11.3`) prints *"Package no longer supported"* on install. In October 2025 Kùzu Inc. was acquired (reporting: by Apple), the GitHub repo was **archived**, and active development/support ended. It remains MIT-licensed and usable; community forks exist (Kineviz **"bighorn"**, **"Ladybug"**) but are early. Adopting Kuzu today means betting on a fork or freezing on an unmaintained pin. Sources: The Register 2025-10-14 "KuzuDB graph database abandoned"; npm deprecation notice on `kuzu`.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 3. Query ergonomics — side-by-side Cypher (where they differ)
|
|
58
|
+
|
|
59
|
+
Q1–Q3 were **byte-identical Cypher** across engines. Q3, Q4, Q5 differed:
|
|
60
|
+
|
|
61
|
+
**Q1 — transitive blocker closure (identical):**
|
|
62
|
+
```cypher
|
|
63
|
+
MATCH (i:Issue {id:'FA#313'})-[:BLOCKED_BY*1..10]->(b:Issue)
|
|
64
|
+
RETURN DISTINCT b.id, b.state ORDER BY b.id
|
|
65
|
+
```
|
|
66
|
+
Both engines accept the `*1..10` variable-length syntax verbatim.
|
|
67
|
+
|
|
68
|
+
**Q3 — orphans (no inbound). DIFFERS:**
|
|
69
|
+
```cypher
|
|
70
|
+
-- Neo4j: pattern-predicate + labels()[0]
|
|
71
|
+
MATCH (n) WHERE NOT ( ()-->(n) ) RETURN labels(n)[0] AS label, count(*) ...
|
|
72
|
+
-- Kuzu: EXISTS-subquery + label() (singular)
|
|
73
|
+
MATCH (n) WHERE NOT EXISTS { MATCH ()-[]->(n) } RETURN label(n) AS label, count(*) ...
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Q4 — duplicate candidates (string/list functions DIFFER):**
|
|
77
|
+
```cypher
|
|
78
|
+
-- Neo4j: split() + list comprehension + substring()
|
|
79
|
+
[w IN split(toLower(t),' ') WHERE size(w)>=5 | substring(w,0,5)]
|
|
80
|
+
-- Kuzu: string_split() + list_transform()/list_filter() + list_contains()
|
|
81
|
+
list_transform(list_filter(string_split(lower(t),' '), x->size(x)>=5), x->substring(x,1,5))
|
|
82
|
+
```
|
|
83
|
+
Note `substring` is **0-indexed in Neo4j, 1-indexed in Kuzu**.
|
|
84
|
+
|
|
85
|
+
**Q5 — shortest path between two decisions. DIFFERS most:**
|
|
86
|
+
```cypher
|
|
87
|
+
-- Neo4j: shortestPath() function + list comprehension over path nodes
|
|
88
|
+
MATCH p=shortestPath((a:Decision {id:'ADR-0011'})-[*..8]-(b:Decision {id:'ADR-0021'}))
|
|
89
|
+
RETURN [n IN nodes(p) | n.id] AS path, length(p)
|
|
90
|
+
-- Kuzu: SHORTEST keyword in the pattern + list_transform for projection
|
|
91
|
+
MATCH p=(a:Decision {id:'ADR-0011'})-[* SHORTEST 1..8]-(b:Decision {id:'ADR-0021'})
|
|
92
|
+
RETURN list_transform(nodes(p), x->x.id) AS path, length(p)
|
|
93
|
+
```
|
|
94
|
+
Kuzu rejected the Neo4j-style `[n IN nodes(p) | n.id]` projection ("Variable n is not in scope") — `list_transform` is the Kuzu idiom. Both returned the same path.
|
|
95
|
+
|
|
96
|
+
**Takeaway:** ~80% of Cypher is portable; the divergence is entirely in (a) existence predicates, (b) string/list stdlib, (c) path projection + shortest-path spelling. A provider abstraction would need a thin dialect shim for exactly those three areas.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 4. What the queries REVEALED (surprises > confirmations)
|
|
101
|
+
|
|
102
|
+
**Q1 — SURPRISE / the headline.** #313's transitive blockers = **{#312 (OPEN), #310 (CLOSED)}** — and *nothing else*. The orchestrator's stated ground truth ("#313's transitive blockers now include #317") **does NOT hold in this snapshot.** No edge from #313 (or its blockers #312/#310) to #317 exists in metadata OR prose; #317 is referenced only by this spike (#318, soft blocker). Verified with a fresh individual `gh issue view` on #313/#312/#310. Interpretation: the intended #313→(knowledge provider #317) dependency is **not yet encoded** — either the edit is still in flight (builds #312/#314 open) or the coupling lives only in humans' heads. *This is exactly the class of gap a graph pass surfaces mechanically: an expected transitive dependency that isn't in the data.* The #310–#314 chain itself is confirmed: #310→{#311,#312,#314}, #312→#313.
|
|
103
|
+
|
|
104
|
+
**Q2 — contradiction candidates: the ADR failure mode caught red-handed.** Top hit is **ADR-0007 vs ADR-0007b** — two files sharing decision number 0007 ("Flow/Skill/Kit/Tool Boundary"), one `Accepted`, one status-less, both citing #62. This is *literally* the numbering-collision + contradiction-accumulation failure that #310 was written to kill, sitting in the current ADR tree. Also surfaced: ADR-0014 (`Proposed`, superseded) contradicting ADR-0015/0016 (`Accepted`) over the same subject (#183, the core-vs-domain boundary), and ADR-0011/0012 (`Accepted`) vs ADR-0021 (`Draft`) over #137. These are real "divergent status over shared subject" pairs.
|
|
105
|
+
|
|
106
|
+
**Q3 — orphans: reveals a modeling lesson, not just data.** "No inbound edge" flags 43 issues, all 40 sessions, 21 decisions, all 13 PRs, all 8 learnings. But Sessions/PRs/Learnings are *source-only node types by construction* (EVIDENCE_OF/CLOSES/MENTIONS all originate from them), so flagging them wholesale is noise. **Finding: orphan detection needs node-type awareness** ("issues/decisions with no inbound" is the meaningful query; leaf-type nodes should be excluded). The genuinely interesting orphans are the 21 Decisions (ADRs) that *nothing* in the backlog references — candidate stale/undiscoverable decisions.
|
|
107
|
+
|
|
108
|
+
**Q4 — duplicate candidates: naive title-token overlap MISSES the known duplicate.** With exact ≥5-char token matching, the ground-truth **traverse#14 ~ traverse#8** duplicate did **not** appear (they share only `extraction`; `chunk` vs `chunking` don't match exactly). It surfaced only after switching to **5-char-prefix stemming** (`extra`,`chunk`), on *both* engines. Lesson: mechanical dup-detection needs stemming + shared-evidence (both issues cite the same 23-item listing-page truncation (downstream consumer pilot) in their *bodies*, which title-only matching can't see — full-text/evidence-ref overlap is required, exactly what #317's "shared evidence refs" clause calls for). Bonus real find: the **runtime-compatibility-canary trio #75/#93/#247** ranks top — recurring near-duplicate canary-failure issues.
|
|
109
|
+
|
|
110
|
+
**Q5 — shortest path.** ADR-0011 ↔ ADR-0021 resolves to `ADR-0011 → FA#137 ← ADR-0021` (length 2): two decisions connected through the backlog issue they both touch. Clean, and a genuinely useful "how are these two decisions related" primitive.
|
|
111
|
+
|
|
112
|
+
AC2 satisfied: all five queries executed on both engines, interpreted against ground truth.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 5. Visualization notes
|
|
117
|
+
|
|
118
|
+
- **Neo4j Browser** (http://localhost:7474) is the real differentiator. Captured screenshot (`neo4j-graph.png`, via Playwright) shows the Browser **connected to the live instance** (`neo4j://localhost:7687`, Community 5.26) rendering `MATCH p=(a:Issue)-[:BLOCKED_BY]->(b:Issue) RETURN p LIMIT 60` as a **d3-force graph — 26 Issue nodes / 27 BLOCKED_BY relationships in several distinct clusters** (the backlog's blocker chains, visually separable at a glance). The left Database Information panel simultaneously confirms the full loaded graph: **Nodes (200)** color-coded by all five labels (Decision, Issue, Learning, PR, Session) and **Relationships (227)** across all five types (BLOCKED_BY, CLOSES, EVIDENCE_OF, MENTIONS, RELATES), plus the property-key catalog (id, state, status, superseded, heuristic, overlap, markerStatus, crossRepo, …). Interactive force-directed exploration, click-to-expand neighborhoods, and color-by-label are its standout value for *human* exploration of the blocker/decision subgraph — Kuzu has no equivalent.
|
|
119
|
+
- **Kuzu** ships **no built-in visualization** in the embedded npm path (Kuzu Explorer exists only as a separate Docker image — which defeats the "zero-ops embedded" pitch). For an embedded engine you bring your own viz (export to a JS graph lib).
|
|
120
|
+
- Screenshot path: `/Users/brian/.claude/jobs/90beb625/tmp/graph-spike/neo4j-graph.png`.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 6. Recommendation: **DEFER adoption** (build the model now, pick the engine later)
|
|
125
|
+
|
|
126
|
+
The spike's own gate ("adoption stays gated on a real query going slow/awkward over file providers") did **not** trip: all five queries ran in milliseconds over 200 nodes / 227 edges. At portfolio scale (hundreds of issues, dozens of decisions, ~120 sessions) this graph is *tiny* — an in-memory JS object graph, or even the throwaway extractor + array scans, answers every canonical query without a database engine at all. **The value proven tonight is the MODEL and the QUERIES, not either engine.**
|
|
127
|
+
|
|
128
|
+
**What to build now (regardless of engine):** the #317 typed graph model (nodes/edges/provenance) + the read-side extractors validated here (metadata markers + prose blockers + ADR/tombstone status + archive index + PR closes). That model is what caught the ADR-0007 collision, the missing #313→#317 edge, and the traverse#14 dup.
|
|
129
|
+
|
|
130
|
+
**Trigger conditions to REVISIT an engine (adopt-when):**
|
|
131
|
+
1. Graph exceeds ~10k nodes / ~50k edges, OR a canonical query (transitive closure, all-pairs shortest path, dup-scan) measurably lags in the naive JS implementation.
|
|
132
|
+
2. Multi-hop/variable-length traversal or shortest-path becomes a *frequent, interactive* need (not batch) — this is where hand-rolled JS gets painful and Cypher pays off.
|
|
133
|
+
3. Interactive human exploration of the knowledge graph becomes a workflow (not just automated health passes) — pulls toward Neo4j Browser specifically.
|
|
134
|
+
|
|
135
|
+
**If/when a trigger fires, prefer Neo4j Community over Kuzu**, primarily because **Kuzu is abandoned upstream (Oct 2025)** — the "zero-ops embedded" advantage is real but is now offset by no maintenance, no security updates, and a fork-or-freeze decision. Neo4j Community is heavier (server + ports) but actively maintained, has the browser, and its Cypher is the portable baseline. *Caveat:* re-evaluate the Kuzu forks (bighorn/Ladybug) at revisit time — if one is credibly maintained, embedded-Kuzu-fork reclaims the zero-ops win for the automated-health-pass use case.
|
|
136
|
+
|
|
137
|
+
**What a provider implementation (#317) would need:**
|
|
138
|
+
- Read-side extractors for each store (validated here): work-item adapter (issues + `work-item-metadata` markers + prose refs), git-repo-docs adapter (ADR/decision status + tombstones + evidence[] + CONTEXT.md vocabulary + learnings), archive-index adapter (sessions). **Robustness note:** 3 of 19 metadata markers failed to JSON-parse and several `blockers[].ref` were `undefined` — the extractor MUST tolerate malformed markers and fall back to prose.
|
|
139
|
+
- A typed node/edge schema (Kuzu proved you *can* enforce types; the model should own the contract independent of storage).
|
|
140
|
+
- Proposal-only writes where the store is human-curated (decision registry, CONTEXT.md).
|
|
141
|
+
- A **dialect shim** if any real engine is used, covering exactly the three divergences found: existence predicates, string/list stdlib (incl. 0- vs 1-indexed substring), and shortest-path/path-projection syntax.
|
|
142
|
+
- Dup-detection needs **stemming + shared-evidence-ref overlap**, not exact title tokens (proven by the traverse#14~#8 miss).
|
|
143
|
+
|
|
144
|
+
AC3 satisfied: explicit adopt/defer recommendation with trigger conditions and provider requirements.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Appendix — artifacts in this scratch dir (auto-cleaned with the job; nothing committed)
|
|
149
|
+
- `build-graph.js` — throwaway extractor → `graph.json` (200 nodes / 227 edges)
|
|
150
|
+
- `kuzu-load.js`, `kuzu-queries.js` — Kuzu embedded loader + 5 queries
|
|
151
|
+
- `neo4j-load.js`, `neo4j-queries.js`, `neo4j-q4-stem.js` — Neo4j loader + queries
|
|
152
|
+
- `graph.json`, `fa-issues.json`, `traverse-issues.json`, `fa-prs.json`, `adr.json` — snapshots
|
|
153
|
+
- `kuzu-db` (+`.wal`) — embedded DB file
|
|
154
|
+
- `neo4j-browser.png` — visualization screenshot
|
|
155
|
+
- Docker container `graph-spike-neo4j` — **torn down at end of session** (see cleanup)
|
|
@@ -50,13 +50,13 @@ Flow Agents may need local schemas for reliability glue that existing standards
|
|
|
50
50
|
|
|
51
51
|
| Format | Purpose | Target Location | Status |
|
|
52
52
|
| --- | --- | --- | --- |
|
|
53
|
-
| Workflow state | Current phase, owner, next action, status, and resumability data | `.flow-agents/<slug>/state.json` | Draft schema: `schemas/workflow-state.schema.json` |
|
|
54
|
-
| Acceptance criteria | Criteria, source request, evidence requirements, and goal-fit status | `.flow-agents/<slug>/acceptance.json` | Draft schema: `schemas/workflow-acceptance.schema.json` |
|
|
55
|
-
| Evidence summary | Proof commands, standard refs, skipped checks, not-verified gaps, and external evidence links | `.flow-agents/<slug>/evidence.json` | Draft schema: `schemas/workflow-evidence.schema.json` |
|
|
56
|
-
| Handoff | What another agent or future session needs to continue safely | `.flow-agents/<slug>/handoff.json` | Draft schema: `schemas/workflow-handoff.schema.json` |
|
|
57
|
-
| Critique record | Reviewer passes, findings, severity, and resolution state for critique loops | `.flow-agents/<slug>/critique.json` | Draft schema: `schemas/workflow-critique.schema.json` |
|
|
58
|
-
| Release readiness | Merge, release, deploy, hold, rollback, docs, and operational readiness decisions | `.flow-agents/<slug>/release.json` | Draft schema: `schemas/workflow-release.schema.json` |
|
|
59
|
-
| Learning record | Repeated failure, correction, pattern, and recommended system update | `.flow-agents/<slug>/learning.json` or `.telemetry/outcomes.jsonl` | Draft schema: `schemas/workflow-learning.schema.json` |
|
|
53
|
+
| Workflow state | Current phase, owner, next action, status, and resumability data | `.kontourai/flow-agents/<slug>/state.json` | Draft schema: `schemas/workflow-state.schema.json` |
|
|
54
|
+
| Acceptance criteria | Criteria, source request, evidence requirements, and goal-fit status | `.kontourai/flow-agents/<slug>/acceptance.json` | Draft schema: `schemas/workflow-acceptance.schema.json` |
|
|
55
|
+
| Evidence summary | Proof commands, standard refs, skipped checks, not-verified gaps, and external evidence links | `.kontourai/flow-agents/<slug>/evidence.json` | Draft schema: `schemas/workflow-evidence.schema.json` |
|
|
56
|
+
| Handoff | What another agent or future session needs to continue safely | `.kontourai/flow-agents/<slug>/handoff.json` | Draft schema: `schemas/workflow-handoff.schema.json` |
|
|
57
|
+
| Critique record | Reviewer passes, findings, severity, and resolution state for critique loops | `.kontourai/flow-agents/<slug>/critique.json` | Draft schema: `schemas/workflow-critique.schema.json` |
|
|
58
|
+
| Release readiness | Merge, release, deploy, hold, rollback, docs, and operational readiness decisions | `.kontourai/flow-agents/<slug>/release.json` | Draft schema: `schemas/workflow-release.schema.json` |
|
|
59
|
+
| Learning record | Repeated failure, correction, pattern, and recommended system update | `.kontourai/flow-agents/<slug>/learning.json` or `.telemetry/outcomes.jsonl` | Draft schema: `schemas/workflow-learning.schema.json` |
|
|
60
60
|
| Context map | Compact project map: structure, commands, conventions, test strategy, Kits, and recent state | Generated under `.flow-agents/` or configurable cache | Planned |
|
|
61
61
|
| Kit Catalog | Product-facing catalog of Flow Kits and their activation, layered over the always-installed standalone base | `kits/catalog.json` plus generated export catalog metadata | Catalog: `kits/catalog.json` |
|
|
62
62
|
| Governance adapter | Optional bridge from Flow Agents evidence gates to tools such as Veritas | `context/contracts/governance-adapter-contract.md` | Draft contract |
|
|
@@ -106,12 +106,91 @@ for the files that declare what CI runs:
|
|
|
106
106
|
|
|
107
107
|
```
|
|
108
108
|
# Trust anchor config — requires owner review.
|
|
109
|
-
# An agent cannot weaken verify-command without a human
|
|
109
|
+
# An agent cannot weaken verify-command or the reconcile manifest without a human
|
|
110
|
+
# approving the change.
|
|
110
111
|
.github/workflows/trust-verify.yml @your-org/owners
|
|
111
112
|
package.json @your-org/owners
|
|
113
|
+
evals/ci/run-baseline.sh @your-org/owners
|
|
112
114
|
```
|
|
113
115
|
|
|
114
|
-
|
|
116
|
+
`package.json` covers both `trust-reconcile-verify` and the `trust-reconcile-manifest`
|
|
117
|
+
declaration (see below); `evals/ci/run-baseline.sh` covers the manifest registry when you
|
|
118
|
+
source the manifest from a `run-baseline.sh`-shaped registry. Adjust paths and team names
|
|
119
|
+
for your repo structure.
|
|
120
|
+
|
|
121
|
+
## Declaring a Manifest (Multiple Commands)
|
|
122
|
+
|
|
123
|
+
The single `trust-reconcile-verify` command above is the anchor's standalone fresh-verify
|
|
124
|
+
(and the legacy reconcile path — a manifest of size 1). To reconcile **granular,
|
|
125
|
+
per-acceptance-criterion** evidence — some commands, some session-local/manual/provider
|
|
126
|
+
evidence — declare a **reconcile manifest**: a set of named, individually-re-runnable
|
|
127
|
+
commands, each of which must actually run in a required CI lane (see ADR 0020).
|
|
128
|
+
|
|
129
|
+
Resolution priority (first match wins):
|
|
130
|
+
|
|
131
|
+
1. CLI `--manifest '<json>'`
|
|
132
|
+
2. `TRUST_RECONCILE_MANIFEST` environment variable (JSON)
|
|
133
|
+
3. `package.json` `"trust-reconcile-manifest"` — either an inline array, or a string
|
|
134
|
+
command that emits the JSON:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"trust-reconcile-manifest": [
|
|
139
|
+
{ "id": "unit", "command": "npm test" },
|
|
140
|
+
{ "id": "lint", "command": "npm run lint" },
|
|
141
|
+
{ "id": "types", "command": "npm run typecheck" }
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Every `id`/`command` here must be a command your required CI actually runs. If your repo
|
|
147
|
+
already has a lane registry that CI invokes, point the key at its machine-readable emit
|
|
148
|
+
instead of duplicating it (this is what Flow Agents does — see the mirror section):
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{ "scripts": { "trust-reconcile-manifest": "bash evals/ci/run-baseline.sh --manifest-json" } }
|
|
152
|
+
```
|
|
153
|
+
4. `evals/ci/run-baseline.sh --manifest-json` (auto-detected, if present).
|
|
154
|
+
|
|
155
|
+
**How classification works.** A claim reconciles per-command against fresh CI results only
|
|
156
|
+
when its evidence is `evidenceType: "test_output"` **and** its command matches a manifest
|
|
157
|
+
entry. Honest session-local evidence (`human_attestation`, `crawl_observation`,
|
|
158
|
+
`document_citation`, `policy_rule`, `source_excerpt`, `attestation`) is never flagged
|
|
159
|
+
"not-run" for lacking a command — it is accepted on its Surface-derived `verified`/`assumed`
|
|
160
|
+
status. A `test_output` claim whose command is not in the manifest is still a divergence
|
|
161
|
+
(you cannot self-label an arbitrary command `test_output` to dodge the manifest).
|
|
162
|
+
|
|
163
|
+
**Session-local passes are loudly, not quietly, marked.** A non-command-backed claim that
|
|
164
|
+
re-derives `verified` (and carries no waiver) is NOT independently re-runnable by CI — the
|
|
165
|
+
anchor can only confirm the bundle is internally self-consistent, not that the underlying
|
|
166
|
+
attestation is true. It prints a distinct line for every such claim:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
[trust-reconcile] ATTESTED (not independently verifiable at L0): '<claimId>' (<claimType>) evidenceType=<type> — accepted on bundle-internal consistency only; see ADR 0020 Residuals
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
plus a summary count (`N attested claim(s) accepted without independent verification`). This
|
|
173
|
+
does not change the exit code — attestations are not blocked, only disclosed — so review the
|
|
174
|
+
`ATTESTED` lines and count in any bundle before trusting it. See the **Residuals** section of
|
|
175
|
+
[ADR 0020](adr/0020-trust-reconcile-manifest-and-claim-classification.md) for the full
|
|
176
|
+
disclosure (fabricated self-consistent attestations, unauthenticated `approved_by`, and the
|
|
177
|
+
evidenceType-laundering route).
|
|
178
|
+
|
|
179
|
+
**Waiving an accepted gap.** For an honestly-accepted gap, record it with both flags:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
npm run workflow:sidecar -- record-evidence <artifact-dir> --verdict pass \
|
|
183
|
+
--check-json '{"id":"load-test","kind":"external","status":"skip","summary":"sustained-load perf test"}' \
|
|
184
|
+
--accepted-gap-reason "load-test env not provisioned this cycle; tracked for the perf milestone" \
|
|
185
|
+
--waived-by "your-name"
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Both `--accepted-gap-reason` and `--waived-by` are required together — an accepted gap
|
|
189
|
+
with no justification or approver is refused (no silent waiver). Reuse a **separate**
|
|
190
|
+
`record-evidence` invocation for waived checks: the flags apply to every check in the
|
|
191
|
+
invocation. The anchor prints each waived claim on a distinct, un-suppressible
|
|
192
|
+
`[trust-reconcile] WAIVED: ...` line in the required job's own log — reviewed and visible,
|
|
193
|
+
never silent.
|
|
115
194
|
|
|
116
195
|
## Configuring the Verify Command
|
|
117
196
|
|
|
@@ -164,9 +243,14 @@ Flow Agents uses the same pattern in its own repository:
|
|
|
164
243
|
|
|
165
244
|
- **`scripts/ci/trust-reconcile.js`** — the anchor script (runs in
|
|
166
245
|
`.github/workflows/trust-reconcile.yml`).
|
|
167
|
-
- **`package.json` `trust-reconcile-verify`** — `npm run build && npm run eval:static
|
|
246
|
+
- **`package.json` `trust-reconcile-verify`** — `npm run build && npm run eval:static`
|
|
247
|
+
(the standalone fresh-verify / legacy single-command reconcile path).
|
|
248
|
+
- **`package.json` `trust-reconcile-manifest`** — `bash evals/ci/run-baseline.sh
|
|
249
|
+
--manifest-json` (the reconcile manifest *is* the live `run-baseline.sh` `LANE_*`
|
|
250
|
+
registry — every entry runs in a required `ci.yml` lane by construction).
|
|
168
251
|
- **`evals/ci/antigaming-suite.sh`** — the regression suite that proves the gate and
|
|
169
|
-
anchor work
|
|
252
|
+
anchor work (including `test_trust_reconcile_manifest.sh` and the end-to-end
|
|
253
|
+
`test_trust_reconcile_mixed_bundle.sh`); runs in the required `ci.yml` lane.
|
|
170
254
|
- **Branch protection** on `main` — `Trust Reconcile` required, `enforce_admins` on.
|
|
171
255
|
|
|
172
256
|
## Adoption Checklist
|
|
@@ -192,6 +276,23 @@ the mismatch. Fix the underlying test failure.
|
|
|
192
276
|
**"trust divergence: command contains exit-code-laundering operator"**: A claimed
|
|
193
277
|
command used `||`, `; true`, or `; exit 0`. These mask real exit codes. Remove them.
|
|
194
278
|
|
|
279
|
+
**"command is not in the reconcile manifest"**: A `test_output` claim named a command that
|
|
280
|
+
is not a manifest entry. Either declare the command in your `trust-reconcile-manifest` (and
|
|
281
|
+
ensure it runs in a required CI lane), or, if the evidence is genuinely session-local
|
|
282
|
+
(manual/provider/observation), record it with a non-`test_output` `evidenceType` so it is
|
|
283
|
+
classified session-local instead of expected to be CI-re-runnable.
|
|
284
|
+
|
|
285
|
+
**"session-local claim ... asserts pass ... but has no waiver and no Surface-derived
|
|
286
|
+
verified/assumed status"**: An honest session-local claim must either resolve a real
|
|
287
|
+
`verified`/`assumed` Surface status from its own evidence, or be explicitly waived with
|
|
288
|
+
`--accepted-gap-reason` + `--waived-by`. Classification is not a pass bypass.
|
|
289
|
+
|
|
195
290
|
**"checkpoint-only bundle cannot be reconciled per-command"**: A `delivery/trust.bundle`
|
|
196
291
|
was expected but only `delivery/trust.checkpoint.json` was found. The deliver skill
|
|
197
292
|
publishes the full bundle; ensure it ran correctly.
|
|
293
|
+
|
|
294
|
+
**"ATTESTED (not independently verifiable at L0): ..."**: Not an error — the job still
|
|
295
|
+
passes. This is the anchor telling you a claim was accepted on bundle-internal consistency
|
|
296
|
+
only (no CI command to re-run and no independent, cryptographically-verified attestation).
|
|
297
|
+
Review each `ATTESTED` line and the summary count before trusting the bundle; see
|
|
298
|
+
[ADR 0020's Residuals section](adr/0020-trust-reconcile-manifest-and-claim-classification.md).
|
|
@@ -69,4 +69,4 @@ Do not treat missing CI, missing required review, missing branch protection data
|
|
|
69
69
|
|
|
70
70
|
## Artifact Lifecycle
|
|
71
71
|
|
|
72
|
-
Local workflow artifacts under `.flow-agents/<slug>/` or a distribution-specific artifact root are runtime/session state by default. Provider records may link to those artifacts, but long-lived decisions should be promoted into durable docs, release notes, changelogs, ADRs, or provider comments/descriptions that are intended to persist.
|
|
72
|
+
Local workflow artifacts under `.kontourai/flow-agents/<slug>/` or a distribution-specific artifact root are runtime/session state by default. Provider records may link to those artifacts, but long-lived decisions should be promoted into durable docs, release notes, changelogs, ADRs, or provider comments/descriptions that are intended to persist.
|
|
@@ -4,7 +4,7 @@ title: Workflow Artifact Lifecycle
|
|
|
4
4
|
|
|
5
5
|
# Workflow Artifact Lifecycle
|
|
6
6
|
|
|
7
|
-
Flow Agents treats task artifacts as useful working memory, not permanent product documentation. Feature branches should promote durable planning, decisions, evidence pointers, and acceptance notes into normal project docs, source, schemas, or provider records instead of carrying `.flow-agents/` runtime files.
|
|
7
|
+
Flow Agents treats task artifacts as useful working memory, not permanent product documentation. Feature branches should promote durable planning, decisions, evidence pointers, and acceptance notes into normal project docs, source, schemas, or provider records instead of carrying `.kontourai/flow-agents/` runtime files.
|
|
8
8
|
|
|
9
9
|
The local artifact root is a current-state dashboard first and a short-lived recovery cache second. It should answer "what needs attention now?" without forcing agents to sift through old successful deliveries.
|
|
10
10
|
|
|
@@ -17,17 +17,19 @@ npm run workflow-artifact-cleanup-audit -- --artifact-root .flow-agents
|
|
|
17
17
|
npm run workflow-artifact-cleanup-audit -- --artifact-root .flow-agents --json
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
+
The default root for local runtime artifacts is `.kontourai/flow-agents`. `.flow-agents` may hold explicit durable Flow Agents config/install state, but it is not a runtime fallback. Move old local sessions with the migration script instead of relying on automatic fallback reads.
|
|
21
|
+
|
|
20
22
|
The command scans immediate workflow directories, skips non-workflow lanes such as `archive/`, and reports active WIP separately from cleanup candidates, terminal done records, active learning follow-ups, and invalid sidecars. This first slice is dry-run classification only: it does not delete, archive, move, or rewrite runtime artifacts by default, and it has no apply mode.
|
|
21
23
|
|
|
22
24
|
Use the Current-State Semantics and Local Retention Policy sections below to interpret each bucket. In particular, learning records with `learning.status: followup_required` or any `routing[].status: open` remain active learning follow-ups until every route is completed, opened elsewhere, deferred with a trigger, accepted, or rejected.
|
|
23
25
|
|
|
24
26
|
## Artifact Lanes
|
|
25
27
|
|
|
26
|
-
Use one local lane under `.flow-agents/`:
|
|
28
|
+
Use one local non-durable lane under `.kontourai/flow-agents/`:
|
|
27
29
|
|
|
28
30
|
| Lane | Path | Commit Policy | Purpose |
|
|
29
31
|
| --- | --- | --- | --- |
|
|
30
|
-
| Runtime workspace | `.flow-agents/<slug>/` | Do not commit | Local session state, sidecars, delegate events, scratch evidence, and recovery notes. |
|
|
32
|
+
| Runtime workspace | `.kontourai/flow-agents/<slug>/` | Do not commit | Local session state, sidecars, delegate events, scratch evidence, and recovery notes. |
|
|
31
33
|
|
|
32
34
|
The runtime workspace stays local because it may contain stale session state, machine-specific paths, or noisy intermediate artifacts. When a branch needs cross-session or cross-person traceability, promote the durable summary, decisions, evidence pointers, and acceptance notes into docs, source, schemas, or provider records instead of committing runtime artifacts.
|
|
33
35
|
|
|
@@ -41,10 +43,71 @@ Treat `state.json` as the active-work signal for local users and `pull-work`.
|
|
|
41
43
|
| `verified` with `next_action.status: continue` | Local evidence passed, but release, final acceptance, or learning is not closed. | Active shepherding candidate. |
|
|
42
44
|
| `verified` with `next_action.status: done` | Evidence passed and the next phase was completed outside the state machine or by a provider record. | Cleanup candidate; should be advanced to a terminal state during final acceptance. |
|
|
43
45
|
| `accepted` with `phase: learning` and `learning.status: followup_required` | Learning was captured but at least one routed follow-up is still open or undecided. | Active learning follow-up until routed to backlog, docs, evals, skills, knowledge, or an explicit deferred trigger. |
|
|
44
|
-
| `delivered`, `accepted`, or `archived` with `phase: done`, or `accepted`/`archived` with closed learning routing | Completed local workflow. |
|
|
46
|
+
| `delivered`, `accepted`, or `archived` with `phase: done`, or `accepted`/`archived` with closed learning routing | Completed local workflow. | Terminal only once a promotion claim is recorded (see [Promote-Then-Archive Gate](#promote-then-archive-gate)); a delivered/accepted session with no promotion claim is a cleanup candidate, not terminal. Retain only while useful for recovery or audit. |
|
|
45
47
|
|
|
46
48
|
`verified` is not a terminal state. It means the verifier supplied evidence. Final acceptance must still record the provider change, CI/release result, docs promotion decision, and any learning route before the workflow stops being active.
|
|
47
49
|
|
|
50
|
+
## Promote-Then-Archive Gate
|
|
51
|
+
|
|
52
|
+
Archiving a delivered session is not a parallel chore to promoting its durable
|
|
53
|
+
residue — it is **gated on** it. The sequence is:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
final acceptance -> promote -> archive
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Durable-residue extraction is the archival act. A delivered session's decisions,
|
|
60
|
+
vocabulary, learnings, and doc updates must be promoted into durable living docs
|
|
61
|
+
(`docs/decisions/<slug>.md`, `CONTEXT.md`, `docs/learnings/*`, `README.md`,
|
|
62
|
+
`context/contracts/`, schemas, provider records) before the session is retired,
|
|
63
|
+
so no delivered work is retired without its knowledge extracted.
|
|
64
|
+
|
|
65
|
+
### The promotion claim
|
|
66
|
+
|
|
67
|
+
The `promote` step records **what was promoted where** and writes a **promotion
|
|
68
|
+
claim** into the session `trust.bundle`:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Real durable residue: each --evidence-path must exist on disk at record time.
|
|
72
|
+
flow-agents workflow-sidecar promote <session-dir> \
|
|
73
|
+
--evidence-path docs/decisions/<slug>.md \
|
|
74
|
+
--evidence-path CONTEXT.md
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The claim is **session-local by construction** (check kind `policy` ->
|
|
78
|
+
`policy_rule` evidence, no command / `execution.label`). It therefore needs **no
|
|
79
|
+
new reconcile-manifest entry** and can **never** become a `[not-run]` /
|
|
80
|
+
unbacked-command divergence at CI `trust-reconcile`: the reconciler classifies it
|
|
81
|
+
session-local and accepts it as an ATTESTED claim. The durable doc paths are the
|
|
82
|
+
claim's evidence refs; each is verified to exist on disk when the claim is
|
|
83
|
+
recorded (a missing path fails loud), and they are mirrored into an auditable
|
|
84
|
+
`promotion.json` in the session directory. The claim is detectable by the archive
|
|
85
|
+
gate and validators via `claim.metadata.promotion` without any manifest change.
|
|
86
|
+
|
|
87
|
+
### Empty-promotion path
|
|
88
|
+
|
|
89
|
+
When a delivered session genuinely produced **no durable residue** (e.g. a pure
|
|
90
|
+
refactor with no decision, vocabulary, or doc change), record an explicit,
|
|
91
|
+
auditable no-residue promotion rather than skipping the gate:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
flow-agents workflow-sidecar promote <session-dir> \
|
|
95
|
+
--none --reason "<why nothing durable was promoted>"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
This still produces a promotion claim (with `none: true` and the reason), so the
|
|
99
|
+
decision that nothing needed promoting is recorded, not silently assumed.
|
|
100
|
+
|
|
101
|
+
### Archive enforcement
|
|
102
|
+
|
|
103
|
+
`workflow-artifact-cleanup-audit` classifies a **delivered or accepted** session
|
|
104
|
+
that reached a terminal shape **without** a promotion claim as a
|
|
105
|
+
`cleanup_candidate` (blocked from archive) with a reason naming the `promote`
|
|
106
|
+
remedy — not `terminal_done`. With the claim (real residue **or** `--none`) it
|
|
107
|
+
classifies `terminal_done` and may be archived. Already-`archived` sessions are
|
|
108
|
+
past the gate and are never re-flagged; this gate is not a backfill of historical
|
|
109
|
+
archives.
|
|
110
|
+
|
|
48
111
|
## Learning Closeout
|
|
49
112
|
|
|
50
113
|
Learning records are a routing surface, not a permanent parking lot.
|
|
@@ -75,13 +138,13 @@ Durable learning should be promoted by target:
|
|
|
75
138
|
|
|
76
139
|
## Local Retention Policy
|
|
77
140
|
|
|
78
|
-
For local-only users, keep enough local state to recover recent work, but do not use `.flow-agents/<slug>/` as the long-term system of record.
|
|
141
|
+
For local-only users, keep enough local state to recover recent work, but do not use `.kontourai/flow-agents/<slug>/` as the long-term system of record.
|
|
79
142
|
|
|
80
143
|
Recommended defaults:
|
|
81
144
|
|
|
82
145
|
| Artifact class | Retain locally | Durable destination |
|
|
83
146
|
| --- | --- | --- |
|
|
84
|
-
| Active WIP, blockers, and unresolved decisions | Until resolved | Current `.flow-agents/<slug>/` state and handoff. |
|
|
147
|
+
| Active WIP, blockers, and unresolved decisions | Until resolved | Current `.kontourai/flow-agents/<slug>/` state and handoff. |
|
|
85
148
|
| Recently merged or accepted deliveries | 14-30 days, or until the next queue audit | PR body, issue comments, release records, promoted docs, or archived evidence refs. |
|
|
86
149
|
| Security, migration, release, or provider-governance evidence | 30-90 days when useful for audit | Provider record, release note, durable doc, or external evidence store. |
|
|
87
150
|
| Routine successful local runtime artifacts | Delete or archive after durable promotion and recovery window | Usually none beyond provider record and docs. |
|
|
@@ -117,10 +180,10 @@ Before merge to `main`:
|
|
|
117
180
|
|
|
118
181
|
1. Promote durable behavior, contracts, decisions, operations notes, and usage guidance into long-lived docs such as `README.md`, `docs/`, `docs/adr/`, schema docs, runbooks, changelogs, or provider records.
|
|
119
182
|
2. Make sure the durable record names the promotion targets and any accepted gaps.
|
|
120
|
-
3. Confirm `.flow-agents/` runtime artifacts remain untracked.
|
|
183
|
+
3. Confirm `.kontourai/flow-agents/` runtime artifacts remain untracked.
|
|
121
184
|
4. Keep links to provider records, durable docs, or archived external evidence instead of relying on temporary local files.
|
|
122
185
|
|
|
123
|
-
`main` must not contain tracked files under `.flow-agents/`. If runtime artifacts still seem necessary after merge, their durable content has not been promoted yet.
|
|
186
|
+
`main` must not contain tracked files under `.kontourai/flow-agents/`. If runtime artifacts still seem necessary after merge, their durable content has not been promoted yet.
|
|
124
187
|
|
|
125
188
|
## Promotion Targets
|
|
126
189
|
|
|
@@ -138,4 +201,4 @@ Do not promote raw intermediate thinking wholesale. Promote the resulting decisi
|
|
|
138
201
|
|
|
139
202
|
## Enforcement
|
|
140
203
|
|
|
141
|
-
Runtime state remains ignored under `.flow-agents/`. Static package validation fails if runtime artifacts are tracked. Reviewers should reject PRs that omit durable docs, source, schema, provider, or evidence updates needed to understand shipped behavior.
|
|
204
|
+
Runtime state remains ignored under `.kontourai/flow-agents/`. Static package validation fails if runtime artifacts are tracked. Reviewers should reject PRs that omit durable docs, source, schema, provider, or evidence updates needed to understand shipped behavior.
|
|
@@ -49,7 +49,7 @@ These check that skill contracts preserve non-negotiable guardrails:
|
|
|
49
49
|
|
|
50
50
|
Static evals prove documented contracts did not drift. They do not prove the agent follows them in conversation.
|
|
51
51
|
|
|
52
|
-
Activation-only behavioral evals may assert no write tools when the goal is trigger and boundary testing. Artifact-quality evals must allow controlled writes to `.flow-agents/<slug>/*.md` and inspect the resulting artifact contracts.
|
|
52
|
+
Activation-only behavioral evals may assert no write tools when the goal is trigger and boundary testing. Artifact-quality evals must allow controlled writes to `.kontourai/flow-agents/<slug>/*.md` and inspect the resulting artifact contracts.
|
|
53
53
|
|
|
54
54
|
### 2. Behavioral Activation Evals
|
|
55
55
|
|
|
@@ -79,7 +79,7 @@ These should verify:
|
|
|
79
79
|
|
|
80
80
|
### 3. Artifact Quality Evals
|
|
81
81
|
|
|
82
|
-
Inspect generated `.flow-agents/<slug>/*.md` files and provider-backed work item drafts for required structure.
|
|
82
|
+
Inspect generated `.kontourai/flow-agents/<slug>/*.md` files and provider-backed work item drafts for required structure.
|
|
83
83
|
|
|
84
84
|
The local artifact-quality gate is:
|
|
85
85
|
|
|
@@ -117,7 +117,7 @@ These cases check that the gates resist pressure and ambiguity:
|
|
|
117
117
|
- CI passes only after unexplained reruns; `evidence-gate` should degrade confidence.
|
|
118
118
|
- Prototype code exists; workflow should require learning review before production promotion.
|
|
119
119
|
- Release notes, rollback, or observability are missing for production-impacting work; `release-readiness` should return `HOLD`, optionally routing missing evidence back to `evidence-gate`.
|
|
120
|
-
- Agent tries to stop with an active `.flow-agents/<slug>/` delivery artifact; `stop-goal-fit` should warn and strict mode should block.
|
|
120
|
+
- Agent tries to stop with an active `.kontourai/flow-agents/<slug>/` delivery artifact; `stop-goal-fit` should warn and strict mode should block.
|
|
121
121
|
- CI/merge acceptance happens but docs are not promoted; release readiness or learning review should record a docs follow-up or explain why durable docs are not needed.
|
|
122
122
|
- Temporary verifier-local sidecar mismatch notes remain in the history; terminal artifacts must show final sidecar reconciliation before reporting clean delivery.
|
|
123
123
|
- Deep-context delivery contains stale shortcuts; agent should ignore stale context and still preserve Definition Of Done, explicit `NOT_VERIFIED`, Goal Fit, and Final Acceptance.
|
|
@@ -27,7 +27,7 @@ That reference is docs-only guidance for new resource-shaped contracts and does
|
|
|
27
27
|
The lifecycle for in-progress and completed workflow artifacts is documented in the Workflow Artifact Lifecycle:
|
|
28
28
|
https://github.com/kontourai/flow-agents/blob/main/docs/workflow-artifact-lifecycle.md
|
|
29
29
|
|
|
30
|
-
Runtime workflow artifacts under `.flow-agents/` remain local and ignored. Completed work must promote durable behavior, decisions, contracts, and evidence into long-lived docs, source, schemas, or provider records before merge to `main`.
|
|
30
|
+
Runtime workflow artifacts under `.kontourai/flow-agents/` remain local and ignored. Explicit durable Flow Agents config/install state may live under `.flow-agents/` when documented, but runtime readers do not fall back there. Completed work must promote durable behavior, decisions, contracts, and evidence into long-lived docs, source, schemas, or provider records before merge to `main`.
|
|
31
31
|
|
|
32
32
|
## How Skills And Agents Use Them
|
|
33
33
|
|