@kontourai/flow-agents 4.0.0 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +8 -0
- package/CHANGELOG.md +34 -0
- package/CONTEXT.md +5 -0
- package/agents/tool-security-reviewer.json +1 -1
- package/build/src/cli/init.js +35 -3
- package/build/src/cli/kit.js +95 -2
- package/build/src/cli/pull-work-provider.js +7 -1
- package/build/src/cli/validate-workflow-artifacts.js +53 -0
- package/build/src/cli/workflow.js +5 -1
- package/build/src/flow-kit/provision.d.ts +23 -0
- package/build/src/flow-kit/provision.js +99 -0
- package/build/src/flow-kit/validate.d.ts +52 -0
- package/build/src/flow-kit/validate.js +214 -9
- package/build/src/runtime-adapters.js +1 -1
- package/context/contracts/execution-contract.md +30 -1
- package/context/contracts/review-contract.md +4 -0
- package/context/contracts/trigger-guards.md +73 -0
- package/context/scripts/telemetry/lib/config.sh +29 -0
- package/context/settings/backlog-provider-settings.json +1 -1
- package/context/settings/workspace-backlog-provider-settings.example.json +1 -1
- package/dist/base/build/package.json +1 -1
- package/dist/base/build/src/cli/init.js +35 -3
- package/dist/base/build/src/cli/kit.js +95 -2
- package/dist/base/build/src/cli/pull-work-provider.js +7 -1
- package/dist/base/build/src/cli/validate-workflow-artifacts.js +53 -0
- package/dist/base/build/src/cli/workflow.js +5 -1
- package/dist/base/build/src/flow-kit/provision.d.ts +23 -0
- package/dist/base/build/src/flow-kit/provision.js +99 -0
- package/dist/base/build/src/flow-kit/validate.d.ts +52 -0
- package/dist/base/build/src/flow-kit/validate.js +214 -9
- package/dist/base/build/src/runtime-adapters.js +1 -1
- package/dist/base/context/contracts/execution-contract.md +30 -1
- package/dist/base/context/contracts/review-contract.md +4 -0
- package/dist/base/context/contracts/trigger-guards.md +73 -0
- package/dist/base/context/scripts/telemetry/lib/config.sh +29 -0
- package/dist/base/context/settings/backlog-provider-settings.json +1 -1
- package/dist/base/context/settings/workspace-backlog-provider-settings.example.json +1 -1
- package/dist/base/docs/adr/0023-kit-provisioning.md +47 -0
- package/dist/base/docs/adr/index.md +1 -0
- package/dist/base/docs/architecture-engine-and-kits.md +17 -0
- package/dist/base/docs/context-map.md +3 -0
- package/dist/base/docs/decisions/backlog-readiness-source.md +89 -0
- package/dist/base/docs/decisions/index.md +1 -0
- package/dist/base/docs/developer-architecture.md +3 -3
- package/dist/base/docs/flow-kit-repository-contract.md +34 -3
- package/dist/base/docs/kit-authoring-guide.md +1 -1
- package/dist/base/docs/veritas-integration.md +12 -0
- package/dist/base/evals/ci/run-baseline.sh +4 -0
- package/dist/base/evals/integration/test_kit_provisioning.sh +112 -0
- package/dist/base/evals/integration/test_liveness_console_relay.sh +91 -1
- package/dist/base/evals/integration/test_liveness_heartbeat.sh +66 -0
- package/dist/base/evals/integration/test_pull_work_provider.sh +18 -0
- package/dist/base/evals/integration/test_veritas_governance_kit.sh +256 -0
- package/dist/base/evals/integration/test_workflow_artifacts.sh +257 -0
- package/dist/base/evals/static/test_package.sh +6 -0
- package/dist/base/evals/static/test_workflow_skills.sh +16 -0
- package/dist/base/install.sh +1 -1
- package/dist/base/kits/builder/flows/publish-learn.flow.json +9 -1
- package/dist/base/kits/builder/skills/execute-plan/SKILL.md +4 -3
- package/dist/base/kits/builder/skills/pull-work/SKILL.md +12 -0
- package/dist/base/kits/builder/skills/review-work/SKILL.md +11 -0
- package/dist/base/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
- package/dist/base/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
- package/dist/base/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
- package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
- package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
- package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
- package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
- package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
- package/dist/base/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
- package/dist/base/kits/veritas-governance/docs/README.md +141 -10
- package/dist/base/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
- package/dist/base/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
- package/dist/base/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
- package/dist/base/kits/veritas-governance/kit.json +65 -0
- package/dist/base/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
- package/dist/base/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
- package/dist/base/schemas/backlog-provider-settings.schema.json +1 -1
- package/dist/base/schemas/workflow-waves.schema.json +347 -0
- package/dist/base/scripts/check-layer-boundary.mjs +98 -0
- package/dist/base/scripts/hooks/claude-telemetry-hook.js +6 -0
- package/dist/base/scripts/hooks/lib/liveness-heartbeat.js +42 -1
- package/dist/base/scripts/hooks/lib/liveness-write.js +109 -9
- package/dist/base/scripts/liveness/relay.sh +23 -11
- package/dist/base/scripts/telemetry/lib/config.sh +29 -0
- package/dist/catalog.json +2 -0
- package/dist/claude-code/.claude/agents/tool-security-reviewer.md +2 -1
- package/dist/claude-code/.claude/skills/consult-standards/SKILL.md +73 -0
- package/dist/claude-code/.claude/skills/execute-plan/SKILL.md +4 -3
- package/dist/claude-code/.claude/skills/pull-work/SKILL.md +12 -0
- package/dist/claude-code/.claude/skills/review-work/SKILL.md +11 -0
- package/dist/claude-code/.claude/skills/standards-authoring/SKILL.md +87 -0
- package/dist/claude-code/build/package.json +1 -1
- package/dist/claude-code/build/src/cli/init.js +35 -3
- package/dist/claude-code/build/src/cli/kit.js +95 -2
- package/dist/claude-code/build/src/cli/pull-work-provider.js +7 -1
- package/dist/claude-code/build/src/cli/validate-workflow-artifacts.js +53 -0
- package/dist/claude-code/build/src/cli/workflow.js +5 -1
- package/dist/claude-code/build/src/flow-kit/provision.d.ts +23 -0
- package/dist/claude-code/build/src/flow-kit/provision.js +99 -0
- package/dist/claude-code/build/src/flow-kit/validate.d.ts +52 -0
- package/dist/claude-code/build/src/flow-kit/validate.js +214 -9
- package/dist/claude-code/build/src/runtime-adapters.js +1 -1
- package/dist/claude-code/context/contracts/execution-contract.md +30 -1
- package/dist/claude-code/context/contracts/review-contract.md +4 -0
- package/dist/claude-code/context/contracts/trigger-guards.md +73 -0
- package/dist/claude-code/context/scripts/telemetry/lib/config.sh +29 -0
- package/dist/claude-code/context/settings/backlog-provider-settings.json +1 -1
- package/dist/claude-code/context/settings/workspace-backlog-provider-settings.example.json +1 -1
- package/dist/claude-code/docs/adr/0023-kit-provisioning.md +47 -0
- package/dist/claude-code/docs/adr/index.md +1 -0
- package/dist/claude-code/docs/architecture-engine-and-kits.md +17 -0
- package/dist/claude-code/docs/context-map.md +3 -0
- package/dist/claude-code/docs/decisions/backlog-readiness-source.md +89 -0
- package/dist/claude-code/docs/decisions/index.md +1 -0
- package/dist/claude-code/docs/developer-architecture.md +3 -3
- package/dist/claude-code/docs/flow-kit-repository-contract.md +34 -3
- package/dist/claude-code/docs/kit-authoring-guide.md +1 -1
- package/dist/claude-code/docs/veritas-integration.md +12 -0
- package/dist/claude-code/evals/ci/run-baseline.sh +4 -0
- package/dist/claude-code/evals/integration/test_kit_provisioning.sh +112 -0
- package/dist/claude-code/evals/integration/test_liveness_console_relay.sh +91 -1
- package/dist/claude-code/evals/integration/test_liveness_heartbeat.sh +66 -0
- package/dist/claude-code/evals/integration/test_pull_work_provider.sh +18 -0
- package/dist/claude-code/evals/integration/test_veritas_governance_kit.sh +256 -0
- package/dist/claude-code/evals/integration/test_workflow_artifacts.sh +257 -0
- package/dist/claude-code/evals/static/test_package.sh +6 -0
- package/dist/claude-code/evals/static/test_workflow_skills.sh +16 -0
- package/dist/claude-code/install.sh +1 -1
- package/dist/claude-code/kits/builder/flows/publish-learn.flow.json +9 -1
- package/dist/claude-code/kits/builder/skills/execute-plan/SKILL.md +4 -3
- package/dist/claude-code/kits/builder/skills/pull-work/SKILL.md +12 -0
- package/dist/claude-code/kits/builder/skills/review-work/SKILL.md +11 -0
- package/dist/claude-code/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
- package/dist/claude-code/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
- package/dist/claude-code/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
- package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
- package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
- package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
- package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
- package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
- package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
- package/dist/claude-code/kits/veritas-governance/docs/README.md +141 -10
- package/dist/claude-code/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
- package/dist/claude-code/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
- package/dist/claude-code/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
- package/dist/claude-code/kits/veritas-governance/kit.json +65 -0
- package/dist/claude-code/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
- package/dist/claude-code/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
- package/dist/claude-code/schemas/backlog-provider-settings.schema.json +1 -1
- package/dist/claude-code/schemas/workflow-waves.schema.json +347 -0
- package/dist/claude-code/scripts/check-layer-boundary.mjs +98 -0
- package/dist/claude-code/scripts/hooks/claude-telemetry-hook.js +6 -0
- package/dist/claude-code/scripts/hooks/lib/liveness-heartbeat.js +42 -1
- package/dist/claude-code/scripts/hooks/lib/liveness-write.js +109 -9
- package/dist/claude-code/scripts/liveness/relay.sh +23 -11
- package/dist/claude-code/scripts/telemetry/lib/config.sh +29 -0
- package/dist/codex/.agents/skills/builder-shape/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/consult-standards/SKILL.md +73 -0
- package/dist/codex/.agents/skills/deliver/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/design-probe/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/execute-plan/SKILL.md +4 -3
- package/dist/codex/.agents/skills/execute-plan/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/fix-bug/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/idea-to-backlog/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/plan-work/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/pull-work/SKILL.md +12 -0
- package/dist/codex/.agents/skills/pull-work/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/review-work/SKILL.md +11 -0
- package/dist/codex/.agents/skills/review-work/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/standards-authoring/SKILL.md +87 -0
- package/dist/codex/.agents/skills/tdd-workflow/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/verify-work/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.codex/agents/tool-security-reviewer.toml +1 -1
- package/dist/codex/build/package.json +1 -1
- package/dist/codex/build/src/cli/init.js +35 -3
- package/dist/codex/build/src/cli/kit.js +95 -2
- package/dist/codex/build/src/cli/pull-work-provider.js +7 -1
- package/dist/codex/build/src/cli/validate-workflow-artifacts.js +53 -0
- package/dist/codex/build/src/cli/workflow.js +5 -1
- package/dist/codex/build/src/flow-kit/provision.d.ts +23 -0
- package/dist/codex/build/src/flow-kit/provision.js +99 -0
- package/dist/codex/build/src/flow-kit/validate.d.ts +52 -0
- package/dist/codex/build/src/flow-kit/validate.js +214 -9
- package/dist/codex/build/src/runtime-adapters.js +1 -1
- package/dist/codex/context/contracts/execution-contract.md +30 -1
- package/dist/codex/context/contracts/review-contract.md +4 -0
- package/dist/codex/context/contracts/trigger-guards.md +73 -0
- package/dist/codex/context/scripts/telemetry/lib/config.sh +29 -0
- package/dist/codex/context/settings/backlog-provider-settings.json +1 -1
- package/dist/codex/context/settings/workspace-backlog-provider-settings.example.json +1 -1
- package/dist/codex/docs/adr/0023-kit-provisioning.md +47 -0
- package/dist/codex/docs/adr/index.md +1 -0
- package/dist/codex/docs/architecture-engine-and-kits.md +17 -0
- package/dist/codex/docs/context-map.md +3 -0
- package/dist/codex/docs/decisions/backlog-readiness-source.md +89 -0
- package/dist/codex/docs/decisions/index.md +1 -0
- package/dist/codex/docs/developer-architecture.md +3 -3
- package/dist/codex/docs/flow-kit-repository-contract.md +34 -3
- package/dist/codex/docs/kit-authoring-guide.md +1 -1
- package/dist/codex/docs/veritas-integration.md +12 -0
- package/dist/codex/evals/ci/run-baseline.sh +4 -0
- package/dist/codex/evals/integration/test_kit_provisioning.sh +112 -0
- package/dist/codex/evals/integration/test_liveness_console_relay.sh +91 -1
- package/dist/codex/evals/integration/test_liveness_heartbeat.sh +66 -0
- package/dist/codex/evals/integration/test_pull_work_provider.sh +18 -0
- package/dist/codex/evals/integration/test_veritas_governance_kit.sh +256 -0
- package/dist/codex/evals/integration/test_workflow_artifacts.sh +257 -0
- package/dist/codex/evals/static/test_package.sh +6 -0
- package/dist/codex/evals/static/test_workflow_skills.sh +16 -0
- package/dist/codex/install.sh +1 -1
- package/dist/codex/kits/builder/flows/publish-learn.flow.json +9 -1
- package/dist/codex/kits/builder/skills/execute-plan/SKILL.md +4 -3
- package/dist/codex/kits/builder/skills/pull-work/SKILL.md +12 -0
- package/dist/codex/kits/builder/skills/review-work/SKILL.md +11 -0
- package/dist/codex/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
- package/dist/codex/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
- package/dist/codex/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
- package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
- package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
- package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
- package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
- package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
- package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
- package/dist/codex/kits/veritas-governance/docs/README.md +141 -10
- package/dist/codex/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
- package/dist/codex/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
- package/dist/codex/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
- package/dist/codex/kits/veritas-governance/kit.json +65 -0
- package/dist/codex/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
- package/dist/codex/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
- package/dist/codex/schemas/backlog-provider-settings.schema.json +1 -1
- package/dist/codex/schemas/workflow-waves.schema.json +347 -0
- package/dist/codex/scripts/check-layer-boundary.mjs +98 -0
- package/dist/codex/scripts/hooks/claude-telemetry-hook.js +6 -0
- package/dist/codex/scripts/hooks/lib/liveness-heartbeat.js +42 -1
- package/dist/codex/scripts/hooks/lib/liveness-write.js +109 -9
- package/dist/codex/scripts/liveness/relay.sh +23 -11
- package/dist/codex/scripts/telemetry/lib/config.sh +29 -0
- package/dist/kiro/agents/tool-security-reviewer.json +1 -1
- package/dist/kiro/build/package.json +1 -1
- package/dist/kiro/build/src/cli/init.js +35 -3
- package/dist/kiro/build/src/cli/kit.js +95 -2
- package/dist/kiro/build/src/cli/pull-work-provider.js +7 -1
- package/dist/kiro/build/src/cli/validate-workflow-artifacts.js +53 -0
- package/dist/kiro/build/src/cli/workflow.js +5 -1
- package/dist/kiro/build/src/flow-kit/provision.d.ts +23 -0
- package/dist/kiro/build/src/flow-kit/provision.js +99 -0
- package/dist/kiro/build/src/flow-kit/validate.d.ts +52 -0
- package/dist/kiro/build/src/flow-kit/validate.js +214 -9
- package/dist/kiro/build/src/runtime-adapters.js +1 -1
- package/dist/kiro/context/contracts/execution-contract.md +30 -1
- package/dist/kiro/context/contracts/review-contract.md +4 -0
- package/dist/kiro/context/contracts/trigger-guards.md +73 -0
- package/dist/kiro/context/scripts/telemetry/lib/config.sh +29 -0
- package/dist/kiro/context/settings/backlog-provider-settings.json +1 -1
- package/dist/kiro/context/settings/workspace-backlog-provider-settings.example.json +1 -1
- package/dist/kiro/docs/adr/0023-kit-provisioning.md +47 -0
- package/dist/kiro/docs/adr/index.md +1 -0
- package/dist/kiro/docs/architecture-engine-and-kits.md +17 -0
- package/dist/kiro/docs/context-map.md +3 -0
- package/dist/kiro/docs/decisions/backlog-readiness-source.md +89 -0
- package/dist/kiro/docs/decisions/index.md +1 -0
- package/dist/kiro/docs/developer-architecture.md +3 -3
- package/dist/kiro/docs/flow-kit-repository-contract.md +34 -3
- package/dist/kiro/docs/kit-authoring-guide.md +1 -1
- package/dist/kiro/docs/veritas-integration.md +12 -0
- package/dist/kiro/evals/ci/run-baseline.sh +4 -0
- package/dist/kiro/evals/integration/test_kit_provisioning.sh +112 -0
- package/dist/kiro/evals/integration/test_liveness_console_relay.sh +91 -1
- package/dist/kiro/evals/integration/test_liveness_heartbeat.sh +66 -0
- package/dist/kiro/evals/integration/test_pull_work_provider.sh +18 -0
- package/dist/kiro/evals/integration/test_veritas_governance_kit.sh +256 -0
- package/dist/kiro/evals/integration/test_workflow_artifacts.sh +257 -0
- package/dist/kiro/evals/static/test_package.sh +6 -0
- package/dist/kiro/evals/static/test_workflow_skills.sh +16 -0
- package/dist/kiro/install.sh +1 -1
- package/dist/kiro/kits/builder/flows/publish-learn.flow.json +9 -1
- package/dist/kiro/kits/builder/skills/execute-plan/SKILL.md +4 -3
- package/dist/kiro/kits/builder/skills/pull-work/SKILL.md +12 -0
- package/dist/kiro/kits/builder/skills/review-work/SKILL.md +11 -0
- package/dist/kiro/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
- package/dist/kiro/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
- package/dist/kiro/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
- package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
- package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
- package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
- package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
- package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
- package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
- package/dist/kiro/kits/veritas-governance/docs/README.md +141 -10
- package/dist/kiro/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
- package/dist/kiro/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
- package/dist/kiro/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
- package/dist/kiro/kits/veritas-governance/kit.json +65 -0
- package/dist/kiro/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
- package/dist/kiro/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
- package/dist/kiro/schemas/backlog-provider-settings.schema.json +1 -1
- package/dist/kiro/schemas/workflow-waves.schema.json +347 -0
- package/dist/kiro/scripts/check-layer-boundary.mjs +98 -0
- package/dist/kiro/scripts/hooks/claude-telemetry-hook.js +6 -0
- package/dist/kiro/scripts/hooks/lib/liveness-heartbeat.js +42 -1
- package/dist/kiro/scripts/hooks/lib/liveness-write.js +109 -9
- package/dist/kiro/scripts/liveness/relay.sh +23 -11
- package/dist/kiro/scripts/telemetry/lib/config.sh +29 -0
- package/dist/opencode/.opencode/agents/tool-security-reviewer.md +2 -1
- package/dist/opencode/.opencode/skills/consult-standards/SKILL.md +73 -0
- package/dist/opencode/.opencode/skills/execute-plan/SKILL.md +4 -3
- package/dist/opencode/.opencode/skills/pull-work/SKILL.md +12 -0
- package/dist/opencode/.opencode/skills/review-work/SKILL.md +11 -0
- package/dist/opencode/.opencode/skills/standards-authoring/SKILL.md +87 -0
- package/dist/opencode/build/package.json +1 -1
- package/dist/opencode/build/src/cli/init.js +35 -3
- package/dist/opencode/build/src/cli/kit.js +95 -2
- package/dist/opencode/build/src/cli/pull-work-provider.js +7 -1
- package/dist/opencode/build/src/cli/validate-workflow-artifacts.js +53 -0
- package/dist/opencode/build/src/cli/workflow.js +5 -1
- package/dist/opencode/build/src/flow-kit/provision.d.ts +23 -0
- package/dist/opencode/build/src/flow-kit/provision.js +99 -0
- package/dist/opencode/build/src/flow-kit/validate.d.ts +52 -0
- package/dist/opencode/build/src/flow-kit/validate.js +214 -9
- package/dist/opencode/build/src/runtime-adapters.js +1 -1
- package/dist/opencode/context/contracts/execution-contract.md +30 -1
- package/dist/opencode/context/contracts/review-contract.md +4 -0
- package/dist/opencode/context/contracts/trigger-guards.md +73 -0
- package/dist/opencode/context/scripts/telemetry/lib/config.sh +29 -0
- package/dist/opencode/context/settings/backlog-provider-settings.json +1 -1
- package/dist/opencode/context/settings/workspace-backlog-provider-settings.example.json +1 -1
- package/dist/opencode/docs/adr/0023-kit-provisioning.md +47 -0
- package/dist/opencode/docs/adr/index.md +1 -0
- package/dist/opencode/docs/architecture-engine-and-kits.md +17 -0
- package/dist/opencode/docs/context-map.md +3 -0
- package/dist/opencode/docs/decisions/backlog-readiness-source.md +89 -0
- package/dist/opencode/docs/decisions/index.md +1 -0
- package/dist/opencode/docs/developer-architecture.md +3 -3
- package/dist/opencode/docs/flow-kit-repository-contract.md +34 -3
- package/dist/opencode/docs/kit-authoring-guide.md +1 -1
- package/dist/opencode/docs/veritas-integration.md +12 -0
- package/dist/opencode/evals/ci/run-baseline.sh +4 -0
- package/dist/opencode/evals/integration/test_kit_provisioning.sh +112 -0
- package/dist/opencode/evals/integration/test_liveness_console_relay.sh +91 -1
- package/dist/opencode/evals/integration/test_liveness_heartbeat.sh +66 -0
- package/dist/opencode/evals/integration/test_pull_work_provider.sh +18 -0
- package/dist/opencode/evals/integration/test_veritas_governance_kit.sh +256 -0
- package/dist/opencode/evals/integration/test_workflow_artifacts.sh +257 -0
- package/dist/opencode/evals/static/test_package.sh +6 -0
- package/dist/opencode/evals/static/test_workflow_skills.sh +16 -0
- package/dist/opencode/install.sh +1 -1
- package/dist/opencode/kits/builder/flows/publish-learn.flow.json +9 -1
- package/dist/opencode/kits/builder/skills/execute-plan/SKILL.md +4 -3
- package/dist/opencode/kits/builder/skills/pull-work/SKILL.md +12 -0
- package/dist/opencode/kits/builder/skills/review-work/SKILL.md +11 -0
- package/dist/opencode/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
- package/dist/opencode/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
- package/dist/opencode/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
- package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
- package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
- package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
- package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
- package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
- package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
- package/dist/opencode/kits/veritas-governance/docs/README.md +141 -10
- package/dist/opencode/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
- package/dist/opencode/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
- package/dist/opencode/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
- package/dist/opencode/kits/veritas-governance/kit.json +65 -0
- package/dist/opencode/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
- package/dist/opencode/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
- package/dist/opencode/schemas/backlog-provider-settings.schema.json +1 -1
- package/dist/opencode/schemas/workflow-waves.schema.json +347 -0
- package/dist/opencode/scripts/check-layer-boundary.mjs +98 -0
- package/dist/opencode/scripts/hooks/claude-telemetry-hook.js +6 -0
- package/dist/opencode/scripts/hooks/lib/liveness-heartbeat.js +42 -1
- package/dist/opencode/scripts/hooks/lib/liveness-write.js +109 -9
- package/dist/opencode/scripts/liveness/relay.sh +23 -11
- package/dist/opencode/scripts/telemetry/lib/config.sh +29 -0
- package/dist/pi/.pi/skills/consult-standards/SKILL.md +73 -0
- package/dist/pi/.pi/skills/execute-plan/SKILL.md +4 -3
- package/dist/pi/.pi/skills/pull-work/SKILL.md +12 -0
- package/dist/pi/.pi/skills/review-work/SKILL.md +11 -0
- package/dist/pi/.pi/skills/standards-authoring/SKILL.md +87 -0
- package/dist/pi/build/package.json +1 -1
- package/dist/pi/build/src/cli/init.js +35 -3
- package/dist/pi/build/src/cli/kit.js +95 -2
- package/dist/pi/build/src/cli/pull-work-provider.js +7 -1
- package/dist/pi/build/src/cli/validate-workflow-artifacts.js +53 -0
- package/dist/pi/build/src/cli/workflow.js +5 -1
- package/dist/pi/build/src/flow-kit/provision.d.ts +23 -0
- package/dist/pi/build/src/flow-kit/provision.js +99 -0
- package/dist/pi/build/src/flow-kit/validate.d.ts +52 -0
- package/dist/pi/build/src/flow-kit/validate.js +214 -9
- package/dist/pi/build/src/runtime-adapters.js +1 -1
- package/dist/pi/context/contracts/execution-contract.md +30 -1
- package/dist/pi/context/contracts/review-contract.md +4 -0
- package/dist/pi/context/contracts/trigger-guards.md +73 -0
- package/dist/pi/context/scripts/telemetry/lib/config.sh +29 -0
- package/dist/pi/context/settings/backlog-provider-settings.json +1 -1
- package/dist/pi/context/settings/workspace-backlog-provider-settings.example.json +1 -1
- package/dist/pi/docs/adr/0023-kit-provisioning.md +47 -0
- package/dist/pi/docs/adr/index.md +1 -0
- package/dist/pi/docs/architecture-engine-and-kits.md +17 -0
- package/dist/pi/docs/context-map.md +3 -0
- package/dist/pi/docs/decisions/backlog-readiness-source.md +89 -0
- package/dist/pi/docs/decisions/index.md +1 -0
- package/dist/pi/docs/developer-architecture.md +3 -3
- package/dist/pi/docs/flow-kit-repository-contract.md +34 -3
- package/dist/pi/docs/kit-authoring-guide.md +1 -1
- package/dist/pi/docs/veritas-integration.md +12 -0
- package/dist/pi/evals/ci/run-baseline.sh +4 -0
- package/dist/pi/evals/integration/test_kit_provisioning.sh +112 -0
- package/dist/pi/evals/integration/test_liveness_console_relay.sh +91 -1
- package/dist/pi/evals/integration/test_liveness_heartbeat.sh +66 -0
- package/dist/pi/evals/integration/test_pull_work_provider.sh +18 -0
- package/dist/pi/evals/integration/test_veritas_governance_kit.sh +256 -0
- package/dist/pi/evals/integration/test_workflow_artifacts.sh +257 -0
- package/dist/pi/evals/static/test_package.sh +6 -0
- package/dist/pi/evals/static/test_workflow_skills.sh +16 -0
- package/dist/pi/install.sh +1 -1
- package/dist/pi/kits/builder/flows/publish-learn.flow.json +9 -1
- package/dist/pi/kits/builder/skills/execute-plan/SKILL.md +4 -3
- package/dist/pi/kits/builder/skills/pull-work/SKILL.md +12 -0
- package/dist/pi/kits/builder/skills/review-work/SKILL.md +11 -0
- package/dist/pi/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
- package/dist/pi/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
- package/dist/pi/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
- package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
- package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
- package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
- package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
- package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
- package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
- package/dist/pi/kits/veritas-governance/docs/README.md +141 -10
- package/dist/pi/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
- package/dist/pi/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
- package/dist/pi/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
- package/dist/pi/kits/veritas-governance/kit.json +65 -0
- package/dist/pi/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
- package/dist/pi/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
- package/dist/pi/schemas/backlog-provider-settings.schema.json +1 -1
- package/dist/pi/schemas/workflow-waves.schema.json +347 -0
- package/dist/pi/scripts/check-layer-boundary.mjs +98 -0
- package/dist/pi/scripts/hooks/claude-telemetry-hook.js +6 -0
- package/dist/pi/scripts/hooks/lib/liveness-heartbeat.js +42 -1
- package/dist/pi/scripts/hooks/lib/liveness-write.js +109 -9
- package/dist/pi/scripts/liveness/relay.sh +23 -11
- package/dist/pi/scripts/telemetry/lib/config.sh +29 -0
- package/docs/adr/0023-kit-provisioning.md +47 -0
- package/docs/adr/index.md +1 -0
- package/docs/architecture-engine-and-kits.md +17 -0
- package/docs/context-map.md +3 -0
- package/docs/decisions/backlog-readiness-source.md +89 -0
- package/docs/decisions/index.md +1 -0
- package/docs/developer-architecture.md +3 -3
- package/docs/flow-kit-repository-contract.md +34 -3
- package/docs/kit-authoring-guide.md +1 -1
- package/docs/veritas-integration.md +12 -0
- package/evals/ci/run-baseline.sh +4 -0
- package/evals/integration/test_kit_provisioning.sh +112 -0
- package/evals/integration/test_liveness_console_relay.sh +91 -1
- package/evals/integration/test_liveness_heartbeat.sh +66 -0
- package/evals/integration/test_pull_work_provider.sh +18 -0
- package/evals/integration/test_veritas_governance_kit.sh +256 -0
- package/evals/integration/test_workflow_artifacts.sh +257 -0
- package/evals/static/test_package.sh +6 -0
- package/evals/static/test_workflow_skills.sh +16 -0
- package/kits/builder/flows/publish-learn.flow.json +9 -1
- package/kits/builder/skills/execute-plan/SKILL.md +4 -3
- package/kits/builder/skills/pull-work/SKILL.md +12 -0
- package/kits/builder/skills/review-work/SKILL.md +11 -0
- package/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
- package/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
- package/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
- package/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
- package/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
- package/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
- package/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
- package/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
- package/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
- package/kits/veritas-governance/docs/README.md +141 -10
- package/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
- package/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
- package/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
- package/kits/veritas-governance/kit.json +65 -0
- package/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
- package/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
- package/package.json +2 -1
- package/schemas/backlog-provider-settings.schema.json +1 -1
- package/schemas/workflow-waves.schema.json +347 -0
- package/scripts/check-layer-boundary.mjs +98 -0
- package/scripts/hooks/claude-telemetry-hook.js +6 -0
- package/scripts/hooks/lib/liveness-heartbeat.js +42 -1
- package/scripts/hooks/lib/liveness-write.js +109 -9
- package/scripts/liveness/relay.sh +23 -11
- package/scripts/telemetry/lib/config.sh +29 -0
- package/src/cli/builder-flow-runtime.test.mjs +86 -0
- package/src/cli/flow-resolver-composition.test.mjs +20 -1
- package/src/cli/init.ts +31 -3
- package/src/cli/kit-metadata-security.test.mjs +163 -1
- package/src/cli/kit-provisioning.test.mjs +122 -0
- package/src/cli/kit.ts +83 -2
- package/src/cli/pull-work-provider.ts +7 -1
- package/src/cli/validate-waves.test.mjs +134 -0
- package/src/cli/validate-workflow-artifacts.ts +47 -0
- package/src/cli/workflow.ts +7 -1
- package/src/flow-kit/provision.ts +118 -0
- package/src/flow-kit/validate.ts +233 -10
- package/src/runtime-adapters.ts +1 -1
|
@@ -7,26 +7,36 @@
|
|
|
7
7
|
# never forked). The Console side ingests this record type and projects the fleet view + runs the
|
|
8
8
|
# janitor (console repo #125); this script is only the flow-agents EMIT half.
|
|
9
9
|
#
|
|
10
|
-
# STRICTLY OPTIONAL and local-first (ADR 0012 §5): a no-op unless
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
# is
|
|
10
|
+
# STRICTLY OPTIONAL and local-first (ADR 0012 §5): a no-op unless the liveness relay is enabled AND a
|
|
11
|
+
# console endpoint is configured. Enablement is conf-driven (#567, parity with economics #469): an
|
|
12
|
+
# operator sets `console_liveness_relay=1` in the console conf (or it defaults on once a console url
|
|
13
|
+
# resolves) — NOT an env var. config.sh (sourced below) is the authoritative, trust-gated decision
|
|
14
|
+
# and also supplies the endpoint/token/tenant from the conf. Best-effort throughout — it must NEVER
|
|
15
|
+
# block, slow, or fail the local liveness write that already happened before this was invoked. Every
|
|
16
|
+
# failure path is a quiet `exit 0`.
|
|
14
17
|
#
|
|
15
18
|
# Invoked (fully detached, best-effort) from scripts/hooks/lib/liveness-write.js after the durable
|
|
16
19
|
# local append. Usage: relay.sh '<liveness-event-json>'
|
|
17
20
|
set -uo pipefail
|
|
18
21
|
|
|
19
|
-
# Opt-in gate — off by default.
|
|
20
|
-
case "${FLOW_AGENTS_CONSOLE_LIVENESS_RELAY:-}" in
|
|
21
|
-
1 | true | TRUE | yes | on) ;;
|
|
22
|
-
*) exit 0 ;;
|
|
23
|
-
esac
|
|
24
|
-
|
|
25
22
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" || exit 0
|
|
26
23
|
|
|
27
24
|
# transport.sh sources ${TELEMETRY_DIR}/lib/redact.sh at load — point it at the telemetry lib dir,
|
|
28
25
|
# then reuse the SAME console POST core the telemetry mirror uses.
|
|
29
26
|
export TELEMETRY_DIR="${TELEMETRY_DIR:-$SCRIPT_DIR/../telemetry}"
|
|
27
|
+
|
|
28
|
+
# Source config.sh FIRST (best-effort, like economics-record.sh) so the conf resolves enablement
|
|
29
|
+
# (FLOW_AGENTS_CONSOLE_LIVENESS_RELAY) and the endpoint/token/tenant — trust-gated for default-path
|
|
30
|
+
# confs. This is what makes conf-only operation work with NO env var set.
|
|
31
|
+
# shellcheck source=/dev/null
|
|
32
|
+
[[ -f "$TELEMETRY_DIR/lib/config.sh" ]] && source "$TELEMETRY_DIR/lib/config.sh" 2>/dev/null || true
|
|
33
|
+
|
|
34
|
+
# Opt-in gate — off by default, now honoring the conf-derived value config.sh just resolved.
|
|
35
|
+
case "${FLOW_AGENTS_CONSOLE_LIVENESS_RELAY:-}" in
|
|
36
|
+
1 | true | TRUE | yes | on) ;;
|
|
37
|
+
*) exit 0 ;;
|
|
38
|
+
esac
|
|
39
|
+
|
|
30
40
|
[[ -f "$TELEMETRY_DIR/lib/transport.sh" ]] || exit 0
|
|
31
41
|
# shellcheck source=/dev/null
|
|
32
42
|
source "$TELEMETRY_DIR/lib/transport.sh" 2>/dev/null || exit 0
|
|
@@ -73,7 +83,9 @@ record="$(printf '%s' "$event_json" | jq -c '{
|
|
|
73
83
|
ttlSeconds: (.ttlSeconds // null),
|
|
74
84
|
host: (.host // null),
|
|
75
85
|
branch: (.branch // null),
|
|
76
|
-
artifact_dir: (.artifact_dir // .artifactDir // null)
|
|
86
|
+
artifact_dir: (.artifact_dir // .artifactDir // null),
|
|
87
|
+
source: (.source // null),
|
|
88
|
+
activity: (.activity // null)
|
|
77
89
|
}' 2>/dev/null)" || exit 0
|
|
78
90
|
[[ -z "$record" || "$record" == "null" ]] && exit 0
|
|
79
91
|
|
|
@@ -109,6 +109,13 @@ FLOW_AGENTS_CONSOLE_ECONOMICS_ENDPOINT_URL="${FLOW_AGENTS_CONSOLE_ECONOMICS_ENDP
|
|
|
109
109
|
# Set (non-empty) only when the config file carries an explicit console_economics_relay key —
|
|
110
110
|
# distinguishes "operator said 0/1" from "key absent" for the default-on rule below.
|
|
111
111
|
console_economics_relay_raw=""
|
|
112
|
+
# Liveness relay (#567): same conf-driven, opt-out-not-silent-off shape as economics (#469) so an
|
|
113
|
+
# operator enables the hosted liveness mirror via console_liveness_relay=1 in the conf, NOT an env
|
|
114
|
+
# var/.profile. A caller-pre-set env var is the starting point; the config key overrides it; absent
|
|
115
|
+
# any key the default-on rule below turns it on once a console telemetry sink resolves.
|
|
116
|
+
FLOW_AGENTS_CONSOLE_LIVENESS_RELAY="${FLOW_AGENTS_CONSOLE_LIVENESS_RELAY:-}"
|
|
117
|
+
FLOW_AGENTS_CONSOLE_LIVENESS_ENDPOINT_URL="${FLOW_AGENTS_CONSOLE_LIVENESS_ENDPOINT_URL:-}"
|
|
118
|
+
console_liveness_relay_raw=""
|
|
112
119
|
# Pricing registry source (consumed by lib/pricing.sh). Explicit file/URL win;
|
|
113
120
|
# otherwise lib/pricing.sh uses the bundled pricing.json offline.
|
|
114
121
|
TELEMETRY_PRICING_FILE="${TELEMETRY_PRICING_FILE:-${FLOW_AGENTS_PRICING_FILE:-}}"
|
|
@@ -164,6 +171,17 @@ if [[ -f "$TELEMETRY_CONFIG_FILE" ]]; then
|
|
|
164
171
|
esac
|
|
165
172
|
;;
|
|
166
173
|
console_economics_endpoint_url) FLOW_AGENTS_CONSOLE_ECONOMICS_ENDPOINT_URL="$value" ;;
|
|
174
|
+
console_liveness_relay)
|
|
175
|
+
case "$(echo "$value" | tr '[:upper:]' '[:lower:]')" in
|
|
176
|
+
1|true|yes|on) console_liveness_relay_raw="1" ;;
|
|
177
|
+
0|false|no|off) console_liveness_relay_raw="0" ;;
|
|
178
|
+
*)
|
|
179
|
+
printf 'warning: config.sh: unrecognized console_liveness_relay value %q; treating as off\n' "$value" >&2
|
|
180
|
+
console_liveness_relay_raw="$value"
|
|
181
|
+
;;
|
|
182
|
+
esac
|
|
183
|
+
;;
|
|
184
|
+
console_liveness_endpoint_url) FLOW_AGENTS_CONSOLE_LIVENESS_ENDPOINT_URL="$value" ;;
|
|
167
185
|
console_pricing_url) TELEMETRY_PRICING_URL="$value" ;;
|
|
168
186
|
pricing_url) TELEMETRY_PRICING_URL="$value" ;;
|
|
169
187
|
pricing_file) TELEMETRY_PRICING_FILE="$value" ;;
|
|
@@ -186,6 +204,17 @@ elif [[ -z "$FLOW_AGENTS_CONSOLE_ECONOMICS_RELAY" \
|
|
|
186
204
|
FLOW_AGENTS_CONSOLE_ECONOMICS_RELAY=1
|
|
187
205
|
fi
|
|
188
206
|
|
|
207
|
+
# Liveness relay default-on rule (#567), identical shape to economics above: an explicit
|
|
208
|
+
# console_liveness_relay config key always wins; otherwise, once a console telemetry sink resolves,
|
|
209
|
+
# the relay defaults ON unless a caller already pre-set FLOW_AGENTS_CONSOLE_LIVENESS_RELAY in the
|
|
210
|
+
# environment. relay.sh's own opt-in gate reads this exact variable.
|
|
211
|
+
if [[ -n "$console_liveness_relay_raw" ]]; then
|
|
212
|
+
FLOW_AGENTS_CONSOLE_LIVENESS_RELAY="$console_liveness_relay_raw"
|
|
213
|
+
elif [[ -z "$FLOW_AGENTS_CONSOLE_LIVENESS_RELAY" \
|
|
214
|
+
&& ( -n "${CONSOLE_TELEMETRY_URL:-}" || -n "${CONSOLE_TELEMETRY_ENDPOINT_URL:-}" ) ]]; then
|
|
215
|
+
FLOW_AGENTS_CONSOLE_LIVENESS_RELAY=1
|
|
216
|
+
fi
|
|
217
|
+
|
|
189
218
|
# Pricing URL is explicit-only (env or config). Do not derive the console
|
|
190
219
|
# pricing endpoint by default; the bundled registry is the reliable offline floor.
|
|
191
220
|
|
|
@@ -1860,6 +1860,92 @@ test("publish-change reports an external capability gap and self-authored result
|
|
|
1860
1860
|
await releaseBuilderFlowAssignment({ sessionDir: session.sessionDir, reason: `test cleanup for ${ambient.actorKey}` });
|
|
1861
1861
|
});
|
|
1862
1862
|
|
|
1863
|
+
async function advanceSessionToPrOpen(session) {
|
|
1864
|
+
await startBuilderFlowSession({ sessionDir: session.sessionDir });
|
|
1865
|
+
const steps = [
|
|
1866
|
+
() => [bundleClaim({ expectation: "selected-work", claimType: "builder.pull-work.selected", subjectType: "work-item" })],
|
|
1867
|
+
() => [
|
|
1868
|
+
bundleClaim({ expectation: "pickup-probe-readiness", claimType: "builder.design-probe.pickup-readiness", subjectType: "work-item" }),
|
|
1869
|
+
bundleClaim({ expectation: "probe-decisions-or-accepted-gaps", claimType: "builder.design-probe.decisions", subjectType: "decision" }),
|
|
1870
|
+
],
|
|
1871
|
+
() => [bundleClaim({ expectation: "implementation-plan", claimType: "builder.plan.implementation", subjectType: "artifact" })],
|
|
1872
|
+
() => [bundleClaim({ expectation: "implementation-scope", claimType: "builder.execute.scope", subjectType: "change" })],
|
|
1873
|
+
() => [bundleClaim({ expectation: "tests-evidence", claimType: "builder.verify.tests", subjectType: "flow-step" }), ...verifiedTestsPrerequisites(session)],
|
|
1874
|
+
() => [bundleClaim({ expectation: "merge-readiness", claimType: "builder.merge-ready.readiness", subjectType: "change" })],
|
|
1875
|
+
];
|
|
1876
|
+
let latest = null;
|
|
1877
|
+
for (const entries of steps) latest = await writeAndSync(session, entries());
|
|
1878
|
+
assert.equal(latest.run.state.current_step, "pr-open");
|
|
1879
|
+
return latest;
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
test("pr-open route-back with missing_evidence returns the run to verify and supports repair re-entry (#695 item a)", async () => {
|
|
1883
|
+
const session = makeSession("propen-routeback");
|
|
1884
|
+
await advanceSessionToPrOpen(session);
|
|
1885
|
+
|
|
1886
|
+
// The #663 wedge scenario: a trust divergence is discovered at pr-open. A failing
|
|
1887
|
+
// pull-request-opened claim declaring the missing_evidence route reason must land
|
|
1888
|
+
// the canonical run back at verify — the sanctioned repair surface — not throw.
|
|
1889
|
+
const failureTimestamp = new Date().toISOString();
|
|
1890
|
+
const routed = await writeAndSync(session, [bundleClaim({
|
|
1891
|
+
expectation: "pull-request-opened",
|
|
1892
|
+
claimType: "builder.pr-open.pull-request",
|
|
1893
|
+
subjectType: "pull-request",
|
|
1894
|
+
status: "fail",
|
|
1895
|
+
routeReason: "missing_evidence",
|
|
1896
|
+
timestamp: failureTimestamp,
|
|
1897
|
+
})]);
|
|
1898
|
+
|
|
1899
|
+
assert.equal(routed.attached, true);
|
|
1900
|
+
assert.equal(routed.run.state.current_step, "verify");
|
|
1901
|
+
const routeBacks = routed.run.state.transitions.filter((transition) => transition.type === "route_back");
|
|
1902
|
+
assert.equal(routeBacks.length, 1);
|
|
1903
|
+
assert.equal(routeBacks[0].from_step, "pr-open");
|
|
1904
|
+
assert.equal(routeBacks[0].to_step, "verify");
|
|
1905
|
+
assert.equal(routeBacks[0].route_reason, "missing_evidence");
|
|
1906
|
+
assert.equal(routeBacks[0].gate_id, "builder.publish-learn:pr-open-gate");
|
|
1907
|
+
assert.equal(routed.projection.flow_run.route_back_attempt, 1);
|
|
1908
|
+
assert.equal(routed.projection.flow_run.route_back_max_attempts, 3);
|
|
1909
|
+
assert.match(routed.projection.next_action.summary, /Route-back history: attempt 1\/3 returned to `verify` for `missing_evidence`/);
|
|
1910
|
+
|
|
1911
|
+
// Repair loop: fresh verify evidence re-passes verify, fresh merge-readiness
|
|
1912
|
+
// re-passes merge-ready, and the run returns to pr-open.
|
|
1913
|
+
const repairedAt = new Date(Date.parse(routed.run.state.transitions.at(-1).at) + 1).toISOString();
|
|
1914
|
+
const reverified = await writeAndSync(session, [
|
|
1915
|
+
withIdentitySuffix(bundleClaim({ expectation: "tests-evidence", claimType: "builder.verify.tests", subjectType: "flow-step", timestamp: repairedAt }), "repair"),
|
|
1916
|
+
...verifiedTestsPrerequisites(session, repairedAt).map((entry, index) => withIdentitySuffix(entry, `repair-${index}`)),
|
|
1917
|
+
]);
|
|
1918
|
+
assert.equal(reverified.run.state.current_step, "merge-ready");
|
|
1919
|
+
const returned = await writeAndSync(session, [
|
|
1920
|
+
withIdentitySuffix(bundleClaim({ expectation: "merge-readiness", claimType: "builder.merge-ready.readiness", subjectType: "change", timestamp: new Date().toISOString() }), "repair"),
|
|
1921
|
+
]);
|
|
1922
|
+
assert.equal(returned.run.state.current_step, "pr-open");
|
|
1923
|
+
});
|
|
1924
|
+
|
|
1925
|
+
test("pr-open route-back with an undeclared reason still throws and mutates nothing", async () => {
|
|
1926
|
+
const session = makeSession("propen-undeclared-reason");
|
|
1927
|
+
await advanceSessionToPrOpen(session);
|
|
1928
|
+
|
|
1929
|
+
const flowDirectory = runDir(session.slug, session.projectRoot);
|
|
1930
|
+
const beforeState = readJson(path.join(flowDirectory, "state.json"));
|
|
1931
|
+
const beforeManifest = readJson(path.join(flowDirectory, FLOW_RUN_EVIDENCE_MANIFEST_PATH));
|
|
1932
|
+
|
|
1933
|
+
writeBundle(session.sessionDir, [bundleClaim({
|
|
1934
|
+
expectation: "pull-request-opened",
|
|
1935
|
+
claimType: "builder.pr-open.pull-request",
|
|
1936
|
+
subjectType: "pull-request",
|
|
1937
|
+
status: "fail",
|
|
1938
|
+
routeReason: "stale_critique",
|
|
1939
|
+
timestamp: new Date().toISOString(),
|
|
1940
|
+
})]);
|
|
1941
|
+
await assert.rejects(
|
|
1942
|
+
() => syncBuilderFlowSession({ sessionDir: session.sessionDir }),
|
|
1943
|
+
/route_reason.*is not declared by gate builder\.publish-learn:pr-open-gate/,
|
|
1944
|
+
);
|
|
1945
|
+
assert.deepEqual(readJson(path.join(flowDirectory, "state.json")), beforeState);
|
|
1946
|
+
assert.deepEqual(readJson(path.join(flowDirectory, FLOW_RUN_EVIDENCE_MANIFEST_PATH)), beforeManifest);
|
|
1947
|
+
});
|
|
1948
|
+
|
|
1863
1949
|
test("recovery loads the slug-bound run, restores every matching projection, and preserves every Flow byte", async () => {
|
|
1864
1950
|
const session = makeSession("recover-active");
|
|
1865
1951
|
await startBuilderFlowSession({ sessionDir: session.sessionDir });
|
|
@@ -4,7 +4,9 @@ import fs from "node:fs";
|
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { validateDefinition } from "@kontourai/flow";
|
|
8
|
+
|
|
9
|
+
import { resolveEffectiveFlowDefinition, resolveFlowFilePath, resolveFlowStep } from "../../build/src/lib/flow-resolver.js";
|
|
8
10
|
|
|
9
11
|
const REPO_ROOT = path.resolve(import.meta.dirname, "../..");
|
|
10
12
|
|
|
@@ -26,6 +28,23 @@ test("effective Builder definition materializes uses_flow and Flow-native comple
|
|
|
26
28
|
);
|
|
27
29
|
});
|
|
28
30
|
|
|
31
|
+
test("composed pr-open-gate declares the missing_evidence repair route to verify (#695 item a)", () => {
|
|
32
|
+
const definition = resolveEffectiveFlowDefinition("builder.build", REPO_ROOT);
|
|
33
|
+
assert.ok(definition);
|
|
34
|
+
const gate = definition.gates["builder.publish-learn:pr-open-gate"];
|
|
35
|
+
assert.deepEqual(gate.on_route_back, { missing_evidence: "verify", default: "verify" });
|
|
36
|
+
assert.deepEqual(gate.route_back_policy, { max_attempts: 3, on_exceeded: "block" });
|
|
37
|
+
// Every declared route-back target must exist in the EFFECTIVE step set — the
|
|
38
|
+
// composed definition (where `verify` lives) must stay a valid Flow definition.
|
|
39
|
+
assert.doesNotThrow(() => validateDefinition(definition));
|
|
40
|
+
// The live resolver surfaces the declared reasons at the composed step, which is
|
|
41
|
+
// what record-gate-claim's --route-reason validation reads.
|
|
42
|
+
const step = resolveFlowStep("builder.build", "pr-open", REPO_ROOT);
|
|
43
|
+
assert.ok(step);
|
|
44
|
+
assert.equal(step.gateId, "builder.publish-learn:pr-open-gate");
|
|
45
|
+
assert.deepEqual([...step.routeBackReasons].sort(), ["default", "missing_evidence"]);
|
|
46
|
+
});
|
|
47
|
+
|
|
29
48
|
test("installed package definitions resolve when a consumer repo has no kits directory", () => {
|
|
30
49
|
const consumer = fs.mkdtempSync(path.join(os.tmpdir(), "flow-agents-consumer-"));
|
|
31
50
|
const resolved = resolveFlowFilePath("builder", "build", "builder.build", consumer, false);
|
package/src/cli/init.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { createInterface } from "node:readline/promises";
|
|
|
8
8
|
import { stdin as input, stdout as output } from "node:process";
|
|
9
9
|
import { parseArgs, flagBool, flagList, flagString } from "../lib/args.js";
|
|
10
10
|
import { activateCodexLocal } from "../runtime-adapters.js";
|
|
11
|
+
import { provisionKit, ProvisionConflictError } from "../flow-kit/provision.js";
|
|
11
12
|
import { main as buildBundles } from "../tools/build-universal-bundles.js";
|
|
12
13
|
import { root } from "../tools/common.js";
|
|
13
14
|
import { defaultCodexHome, durableInstallRecordPath, skillsManifestPath } from "../lib/local-artifact-root.js";
|
|
@@ -640,7 +641,21 @@ function installBundle(bundle: string, options: InitOptions): number {
|
|
|
640
641
|
return result.status ?? 1;
|
|
641
642
|
}
|
|
642
643
|
|
|
643
|
-
function
|
|
644
|
+
function kitPathForInit(kitId: string, dest: string): string | null {
|
|
645
|
+
const catalogPath = path.join(root, "kits", "catalog.json");
|
|
646
|
+
if (fs.existsSync(catalogPath)) {
|
|
647
|
+
const catalog = JSON.parse(fs.readFileSync(catalogPath, "utf8")) as { kits?: unknown[] };
|
|
648
|
+
const entry = Array.isArray(catalog.kits)
|
|
649
|
+
? catalog.kits.find((item) => typeof item === "object" && item !== null && (item as Record<string, unknown>).id === kitId)
|
|
650
|
+
: undefined;
|
|
651
|
+
const rel = entry && typeof entry === "object" ? (entry as Record<string, unknown>).path : undefined;
|
|
652
|
+
if (typeof rel === "string") return path.resolve(root, rel);
|
|
653
|
+
}
|
|
654
|
+
const installed = path.join(dest, "kits", "local", "repositories", kitId);
|
|
655
|
+
return fs.existsSync(installed) ? installed : null;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
async function activateKits(options: InitOptions): Promise<number> {
|
|
644
659
|
const activeKitIds = options.activeKitIds ?? [];
|
|
645
660
|
if (!options.activateKits || activeKitIds.length === 0 || options.runtime !== "codex") return 0;
|
|
646
661
|
const result = activateCodexLocal(options.dest, options.dest, { kitIdFilter: activeKitIds });
|
|
@@ -650,6 +665,19 @@ function activateKits(options: InitOptions): number {
|
|
|
650
665
|
}
|
|
651
666
|
const generated = Array.isArray(result.generated_runtime_files) ? result.generated_runtime_files : [];
|
|
652
667
|
console.log(`Activated ${generated.length} Codex local runtime asset(s)`);
|
|
668
|
+
for (const kitId of activeKitIds) {
|
|
669
|
+
const kitDir = kitPathForInit(kitId, options.dest);
|
|
670
|
+
if (!kitDir) throw new Error(`activated kit '${kitId}' could not be resolved for provisioning`);
|
|
671
|
+
try {
|
|
672
|
+
const provisioned = await provisionKit(kitDir, options.dest);
|
|
673
|
+
if (provisioned.files.length > 0) console.log(`Provisioned ${provisioned.files.length} file(s) from kit '${kitId}'`);
|
|
674
|
+
} catch (error) {
|
|
675
|
+
if (!(error instanceof ProvisionConflictError)) throw error;
|
|
676
|
+
for (const conflict of error.conflicts) {
|
|
677
|
+
console.warn(`flow-agents init: warning: skipped existing provision '${conflict.target}' from kit '${kitId}'`);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
}
|
|
653
681
|
return 0;
|
|
654
682
|
}
|
|
655
683
|
|
|
@@ -867,7 +895,7 @@ export async function main(argv = process.argv.slice(2)): Promise<number> {
|
|
|
867
895
|
const installed = result.status ?? 1;
|
|
868
896
|
if (installed !== 0) return installed;
|
|
869
897
|
writeInstallRecord(options.dest, "codex", true, options.activeKitIds ?? []);
|
|
870
|
-
return activateKits(options);
|
|
898
|
+
return await activateKits(options);
|
|
871
899
|
}
|
|
872
900
|
// --global for pi: NOT_VERIFIED (no documented global dir). Warn and fall through to workspace install.
|
|
873
901
|
if (options.global && options.runtime === "pi") {
|
|
@@ -881,7 +909,7 @@ export async function main(argv = process.argv.slice(2)): Promise<number> {
|
|
|
881
909
|
const installed = installBundle(bundle, options);
|
|
882
910
|
if (installed !== 0) return installed;
|
|
883
911
|
writeInstallRecord(options.dest, options.runtime, options.global, options.activeKitIds ?? []);
|
|
884
|
-
const activated = activateKits(options);
|
|
912
|
+
const activated = await activateKits(options);
|
|
885
913
|
// G2/G3: shared post-install auto-verify + summary tail. Applies
|
|
886
914
|
// identically whether main() reached here via headlessOptions() or
|
|
887
915
|
// interactiveOptions() -- never changes `activated`'s exit code.
|
|
@@ -7,7 +7,7 @@ import { createRequire, syncBuiltinESMExports } from "node:module";
|
|
|
7
7
|
|
|
8
8
|
import { readKitInventory } from "../../build/src/runtime-adapters.js";
|
|
9
9
|
import { main as validateHookInfluence } from "../../build/src/cli/validate-hook-influence.js";
|
|
10
|
-
import { parseKitFlowStepActions, parseKitSkillRoles, validateKitRepository } from "../../build/src/flow-kit/validate.js";
|
|
10
|
+
import { parseKitAgentSpawnTriggers, parseKitFlowStepActions, parseKitSkillRoles, validateKitRepository, validateKitRepositoryDiagnostics } from "../../build/src/flow-kit/validate.js";
|
|
11
11
|
import { observeBuilderArtifactsForProgress } from "../../build/src/builder-gate-action-envelope.js";
|
|
12
12
|
|
|
13
13
|
const require = createRequire(import.meta.url);
|
|
@@ -908,3 +908,165 @@ test("workflowTriggersFor returns Knowledge's structured capture trigger", () =>
|
|
|
908
908
|
assert.match(trigger.steering, /Keep the session on `knowledge\.ingest`/);
|
|
909
909
|
assert.match(trigger.steering, /unsupported-runtime blocker/);
|
|
910
910
|
});
|
|
911
|
+
|
|
912
|
+
test("agent spawn trigger metadata accepts a fully guarded declaration without errors or warnings", () => {
|
|
913
|
+
const result = parseKitAgentSpawnTriggers({
|
|
914
|
+
agent_spawn_triggers: [
|
|
915
|
+
{
|
|
916
|
+
id: "on-check-failure",
|
|
917
|
+
description: "Escalates failing checks to a headless agent run.",
|
|
918
|
+
spawns_agent_runs: true,
|
|
919
|
+
guards: { dedup_key: "check-name+failure-signature", cooldown_seconds: 900, daily_cap: 20, max_concurrent: 1 },
|
|
920
|
+
},
|
|
921
|
+
{
|
|
922
|
+
id: "notify-only",
|
|
923
|
+
description: "Fires a notification; never spawns agent runs.",
|
|
924
|
+
spawns_agent_runs: false,
|
|
925
|
+
},
|
|
926
|
+
],
|
|
927
|
+
}, "fixture/kit.json");
|
|
928
|
+
|
|
929
|
+
assert.deepEqual(result.errors, []);
|
|
930
|
+
assert.deepEqual(result.warnings, []);
|
|
931
|
+
assert.equal(result.entries.length, 2);
|
|
932
|
+
assert.deepEqual(result.entries[0].guards, { dedup_key: "check-name+failure-signature", cooldown_seconds: 900, daily_cap: 20, max_concurrent: 1 });
|
|
933
|
+
assert.equal(result.entries[1].guards, undefined);
|
|
934
|
+
});
|
|
935
|
+
|
|
936
|
+
test("agent spawn trigger without guards warns (never errors) when it spawns agent runs", () => {
|
|
937
|
+
const missing = parseKitAgentSpawnTriggers({
|
|
938
|
+
agent_spawn_triggers: [
|
|
939
|
+
{ id: "on-schedule", description: "Scheduled automation spawning agent runs.", spawns_agent_runs: true },
|
|
940
|
+
],
|
|
941
|
+
}, "fixture/kit.json");
|
|
942
|
+
assert.deepEqual(missing.errors, []);
|
|
943
|
+
assert.equal(missing.warnings.length, 1);
|
|
944
|
+
assert.match(missing.warnings[0], /agent_spawn_triggers\[0\] \('on-schedule'\) spawns agent runs without complete guard config/);
|
|
945
|
+
assert.match(missing.warnings[0], /missing: dedup_key, cooldown_seconds, daily_cap, max_concurrent/);
|
|
946
|
+
assert.match(missing.warnings[0], /context\/contracts\/trigger-guards\.md/);
|
|
947
|
+
assert.equal(missing.entries.length, 1);
|
|
948
|
+
|
|
949
|
+
const incomplete = parseKitAgentSpawnTriggers({
|
|
950
|
+
agent_spawn_triggers: [
|
|
951
|
+
{ id: "on-check-failure", description: "Escalation.", spawns_agent_runs: true, guards: { cooldown_seconds: 900 } },
|
|
952
|
+
],
|
|
953
|
+
}, "fixture/kit.json");
|
|
954
|
+
assert.deepEqual(incomplete.errors, []);
|
|
955
|
+
assert.equal(incomplete.warnings.length, 1);
|
|
956
|
+
assert.match(incomplete.warnings[0], /missing: dedup_key, daily_cap, max_concurrent/);
|
|
957
|
+
|
|
958
|
+
const nonSpawning = parseKitAgentSpawnTriggers({
|
|
959
|
+
agent_spawn_triggers: [
|
|
960
|
+
{ id: "notify-only", description: "Notification only.", spawns_agent_runs: false },
|
|
961
|
+
],
|
|
962
|
+
}, "fixture/kit.json");
|
|
963
|
+
assert.deepEqual(nonSpawning.errors, []);
|
|
964
|
+
assert.deepEqual(nonSpawning.warnings, []);
|
|
965
|
+
});
|
|
966
|
+
|
|
967
|
+
test("agent spawn trigger metadata rejects malformed shapes as errors", () => {
|
|
968
|
+
const notAList = parseKitAgentSpawnTriggers({ agent_spawn_triggers: {} }, "fixture/kit.json");
|
|
969
|
+
assert.match(notAList.errors.join("\n"), /\.agent_spawn_triggers must be a list/);
|
|
970
|
+
|
|
971
|
+
const result = parseKitAgentSpawnTriggers({
|
|
972
|
+
agent_spawn_triggers: [
|
|
973
|
+
{ id: "Bad Id", description: "x", spawns_agent_runs: true },
|
|
974
|
+
{ id: "dup", description: "x", spawns_agent_runs: true, guards: { dedup_key: "sig", cooldown_seconds: 900, daily_cap: 20, max_concurrent: 1 } },
|
|
975
|
+
{ id: "dup", description: "x", spawns_agent_runs: true, guards: { dedup_key: "sig", cooldown_seconds: 900, daily_cap: 20, max_concurrent: 1 } },
|
|
976
|
+
{ id: "no-description", spawns_agent_runs: true },
|
|
977
|
+
{ id: "no-boolean", description: "x", spawns_agent_runs: "yes" },
|
|
978
|
+
{ id: "bad-guards", description: "x", spawns_agent_runs: true, guards: [] },
|
|
979
|
+
{ id: "bad-guard-values", description: "x", spawns_agent_runs: true, guards: { dedup_key: " ", cooldown_seconds: 0, daily_cap: 1.5, max_concurrent: -1 } },
|
|
980
|
+
{ id: "unknown-guard", description: "x", spawns_agent_runs: true, guards: { dedup_key: "sig", cooldown_seconds: 900, daily_cap: 20, max_concurrent: 1, burst: 5 } },
|
|
981
|
+
{ id: "unknown-field", description: "x", spawns_agent_runs: true, command: "private-bypass" },
|
|
982
|
+
],
|
|
983
|
+
}, "fixture/kit.json");
|
|
984
|
+
|
|
985
|
+
const errors = result.errors.join("\n");
|
|
986
|
+
assert.match(errors, /agent_spawn_triggers\[0\]\.id must match/);
|
|
987
|
+
assert.match(errors, /agent_spawn_triggers\[2\]\.id duplicates 'dup'/);
|
|
988
|
+
assert.match(errors, /agent_spawn_triggers\[3\]\.description must be a non-empty string/);
|
|
989
|
+
assert.match(errors, /agent_spawn_triggers\[4\]\.spawns_agent_runs must be a boolean/);
|
|
990
|
+
assert.match(errors, /agent_spawn_triggers\[5\]\.guards must be an object/);
|
|
991
|
+
assert.match(errors, /agent_spawn_triggers\[6\]\.guards\.dedup_key must be a non-empty string/);
|
|
992
|
+
assert.match(errors, /agent_spawn_triggers\[6\]\.guards\.cooldown_seconds must be an integer >= 1/);
|
|
993
|
+
assert.match(errors, /agent_spawn_triggers\[6\]\.guards\.daily_cap must be an integer >= 1/);
|
|
994
|
+
assert.match(errors, /agent_spawn_triggers\[6\]\.guards\.max_concurrent must be an integer >= 1/);
|
|
995
|
+
assert.match(errors, /agent_spawn_triggers\[7\]\.guards contains unsupported field\(s\): burst/);
|
|
996
|
+
assert.match(errors, /agent_spawn_triggers\[8\] contains unsupported field\(s\): command/);
|
|
997
|
+
// Malformed entries fail shape validation; only the first 'dup' entry (valid shape) parses.
|
|
998
|
+
assert.equal(result.entries.length, 1);
|
|
999
|
+
// Shape violations are errors, never demoted to the guard-completeness warning channel.
|
|
1000
|
+
assert.deepEqual(result.warnings, []);
|
|
1001
|
+
});
|
|
1002
|
+
|
|
1003
|
+
test("kit repository diagnostics carry the guardless-spawn warning and never leak it into errors", async () => {
|
|
1004
|
+
const root = tempRoot("flow-agents-agent-spawn-trigger-repo-");
|
|
1005
|
+
const kit = path.join(root, "builder");
|
|
1006
|
+
fs.cpSync("kits/builder", kit, { recursive: true });
|
|
1007
|
+
const manifestFile = path.join(kit, "kit.json");
|
|
1008
|
+
const manifest = JSON.parse(fs.readFileSync(manifestFile, "utf8"));
|
|
1009
|
+
manifest.agent_spawn_triggers = [
|
|
1010
|
+
{ id: "on-check-failure", description: "Escalates failing checks to a headless agent run.", spawns_agent_runs: true },
|
|
1011
|
+
];
|
|
1012
|
+
writeJson(manifestFile, manifest);
|
|
1013
|
+
|
|
1014
|
+
const diagnostics = await validateKitRepositoryDiagnostics(kit);
|
|
1015
|
+
assert.deepEqual(diagnostics.errors, []);
|
|
1016
|
+
assert.equal(diagnostics.warnings.length, 1);
|
|
1017
|
+
assert.match(diagnostics.warnings[0], /spawns agent runs without complete guard config/);
|
|
1018
|
+
// validateKitRepository keeps its errors-only contract: a warning is not an error.
|
|
1019
|
+
assert.deepEqual(await validateKitRepository(kit), []);
|
|
1020
|
+
|
|
1021
|
+
// A fully guarded declaration is clean on both channels.
|
|
1022
|
+
manifest.agent_spawn_triggers[0].guards = { dedup_key: "check-name+failure-signature", cooldown_seconds: 900, daily_cap: 20, max_concurrent: 1 };
|
|
1023
|
+
writeJson(manifestFile, manifest);
|
|
1024
|
+
const guarded = await validateKitRepositoryDiagnostics(kit);
|
|
1025
|
+
assert.deepEqual(guarded.errors, []);
|
|
1026
|
+
assert.deepEqual(guarded.warnings, []);
|
|
1027
|
+
|
|
1028
|
+
// agent_spawn_triggers is recognized Flow Agents metadata, not a third-party namespace.
|
|
1029
|
+
const { deriveKitTargets } = await import("../../build/src/flow-kit/validate.js");
|
|
1030
|
+
const targets = await deriveKitTargets(manifest, kit);
|
|
1031
|
+
assert.deepEqual(targets.third_party_extensions, []);
|
|
1032
|
+
});
|
|
1033
|
+
|
|
1034
|
+
test("kit install surfaces the guardless-spawn warning non-blockingly for BOTH source forms (local path and git URL)", async () => {
|
|
1035
|
+
const { execFileSync } = await import("node:child_process");
|
|
1036
|
+
const root = tempRoot("flow-agents-agent-spawn-trigger-install-");
|
|
1037
|
+
const kitSource = path.join(root, "guarded-kit");
|
|
1038
|
+
fs.mkdirSync(path.join(kitSource, "flows"), { recursive: true });
|
|
1039
|
+
writeJson(path.join(kitSource, "kit.json"), {
|
|
1040
|
+
schema_version: "1.0",
|
|
1041
|
+
id: "guardless-demo",
|
|
1042
|
+
name: "Guardless Demo Kit",
|
|
1043
|
+
flows: [{ id: "demo.flow", path: "flows/demo.flow.json" }],
|
|
1044
|
+
agent_spawn_triggers: [
|
|
1045
|
+
{ id: "on-check-failure", description: "Escalates failing checks to a headless agent run.", spawns_agent_runs: true },
|
|
1046
|
+
],
|
|
1047
|
+
});
|
|
1048
|
+
writeJson(path.join(kitSource, "flows", "demo.flow.json"), {
|
|
1049
|
+
id: "demo.flow",
|
|
1050
|
+
version: "1.0",
|
|
1051
|
+
steps: [{ id: "only", next: null }],
|
|
1052
|
+
gates: {},
|
|
1053
|
+
});
|
|
1054
|
+
const cli = path.resolve("build/src/cli.js");
|
|
1055
|
+
const runInstall = (source, destName) => {
|
|
1056
|
+
return execFileSync(process.execPath, [cli, "kit", "install", source, "--dest", path.join(root, destName)], { encoding: "utf8" });
|
|
1057
|
+
};
|
|
1058
|
+
|
|
1059
|
+
// Local-path source form.
|
|
1060
|
+
const localOut = runInstall(kitSource, "dest-local");
|
|
1061
|
+
assert.match(localOut, /warning: .*agent_spawn_triggers\[0\] \('on-check-failure'\) spawns agent runs without complete guard config/);
|
|
1062
|
+
assert.match(localOut, /installed local kit 'guardless-demo'/);
|
|
1063
|
+
|
|
1064
|
+
// Git-URL source form (file:// clone of the same kit).
|
|
1065
|
+
const git = (args, cwd) => execFileSync("git", ["-c", "user.email=kit-test@example.invalid", "-c", "user.name=kit-test", ...args], { cwd, encoding: "utf8" });
|
|
1066
|
+
git(["init", "--quiet"], kitSource);
|
|
1067
|
+
git(["add", "-A"], kitSource);
|
|
1068
|
+
git(["commit", "--quiet", "-m", "kit fixture"], kitSource);
|
|
1069
|
+
const gitOut = runInstall(`file://${kitSource}`, "dest-git");
|
|
1070
|
+
assert.match(gitOut, /warning: .*agent_spawn_triggers\[0\] \('on-check-failure'\) spawns agent runs without complete guard config/);
|
|
1071
|
+
assert.match(gitOut, /installed git kit 'guardless-demo'/);
|
|
1072
|
+
});
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
7
|
+
|
|
8
|
+
import { validateKitRepository } from "../../build/src/flow-kit/validate.js";
|
|
9
|
+
import { provisionKit, ProvisionConflictError } from "../../build/src/flow-kit/provision.js";
|
|
10
|
+
|
|
11
|
+
const FLOW = {
|
|
12
|
+
id: "fixture.review",
|
|
13
|
+
version: "1.0",
|
|
14
|
+
steps: [{ id: "review", next: "done" }, { id: "done", next: null }],
|
|
15
|
+
gates: {},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function fixture(provisions) {
|
|
19
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-unit-"));
|
|
20
|
+
fs.mkdirSync(path.join(dir, "flows"));
|
|
21
|
+
fs.mkdirSync(path.join(dir, "payload"));
|
|
22
|
+
fs.writeFileSync(path.join(dir, "flows", "review.flow.json"), JSON.stringify(FLOW));
|
|
23
|
+
fs.writeFileSync(path.join(dir, "payload", "one.txt"), "one-new\n");
|
|
24
|
+
fs.writeFileSync(path.join(dir, "payload", "two.txt"), "two-new\n");
|
|
25
|
+
fs.writeFileSync(path.join(dir, "kit.json"), JSON.stringify({
|
|
26
|
+
schema_version: "1.0",
|
|
27
|
+
id: "fixture",
|
|
28
|
+
name: "Fixture",
|
|
29
|
+
flows: [{ id: "fixture.review", path: "flows/review.flow.json" }],
|
|
30
|
+
provisions,
|
|
31
|
+
}));
|
|
32
|
+
return dir;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const entry = (id, source, target) => ({ id: `fixture.${id}`, path: `payload/${source}`, target });
|
|
36
|
+
|
|
37
|
+
test("provision validation rejects unsafe and duplicate normalized targets", async () => {
|
|
38
|
+
const cases = [
|
|
39
|
+
[[entry("one", "one.txt", "../escape.txt")], "traversal segments"],
|
|
40
|
+
[[entry("one", "one.txt", path.resolve("/tmp/escape.txt"))], "must be relative"],
|
|
41
|
+
[[entry("one", "one.txt", ".git/config")], "must not be inside .git"],
|
|
42
|
+
[[entry("one", "one.txt", ".GIT/hooks/pre-push")], "must not be inside .git"],
|
|
43
|
+
[[entry("one", "one.txt", "docs//same.txt"), entry("two", "two.txt", "docs/same.txt")], "target duplicates"],
|
|
44
|
+
[[entry("one", "one.txt", "README.md"), entry("two", "two.txt", "readme.md")], "target duplicates"],
|
|
45
|
+
[[entry("one", "one.txt", ".kontourai/flow-agents/provisions/fixture.json")], "provision manifest namespace"],
|
|
46
|
+
[[{ id: "fixture.one", path: "payload/../payload/one.txt", target: "out.txt" }], "must not contain traversal segments"],
|
|
47
|
+
];
|
|
48
|
+
for (const [provisions, message] of cases) {
|
|
49
|
+
const errors = await validateKitRepository(fixture(provisions));
|
|
50
|
+
assert.equal(errors.some((error) => error.includes(message)), true, errors.join("\n"));
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("provision core preflights conflicts before writing and force overwrites", async () => {
|
|
55
|
+
const kit = fixture([entry("one", "one.txt", "docs/one.txt"), entry("two", "two.txt", "docs/two.txt")]);
|
|
56
|
+
const target = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-target-"));
|
|
57
|
+
fs.mkdirSync(path.join(target, "docs"));
|
|
58
|
+
fs.writeFileSync(path.join(target, "docs", "two.txt"), "keep\n");
|
|
59
|
+
|
|
60
|
+
await assert.rejects(() => provisionKit(kit, target), (error) => error instanceof ProvisionConflictError && error.conflicts.length === 1);
|
|
61
|
+
assert.equal(fs.existsSync(path.join(target, "docs", "one.txt")), false);
|
|
62
|
+
assert.equal(fs.readFileSync(path.join(target, "docs", "two.txt"), "utf8"), "keep\n");
|
|
63
|
+
|
|
64
|
+
const result = await provisionKit(kit, target, { force: true });
|
|
65
|
+
assert.equal(fs.readFileSync(path.join(target, "docs", "one.txt"), "utf8"), "one-new\n");
|
|
66
|
+
assert.equal(fs.readFileSync(path.join(target, "docs", "two.txt"), "utf8"), "two-new\n");
|
|
67
|
+
const manifest = JSON.parse(fs.readFileSync(result.manifest_path, "utf8"));
|
|
68
|
+
assert.equal(manifest.schema_version, "1.0");
|
|
69
|
+
assert.equal(manifest.kit_id, "fixture");
|
|
70
|
+
assert.match(manifest.kit_hash, /^sha256:[a-f0-9]{64}$/);
|
|
71
|
+
assert.deepEqual(manifest.files, [{ id: "fixture.one", target: "docs/one.txt" }, { id: "fixture.two", target: "docs/two.txt" }]);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("provision core dry-run writes neither files nor manifest", async () => {
|
|
75
|
+
const kit = fixture([entry("one", "one.txt", "docs/one.txt")]);
|
|
76
|
+
const target = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-dry-"));
|
|
77
|
+
const result = await provisionKit(kit, target, { dryRun: true });
|
|
78
|
+
assert.equal(result.dry_run, true);
|
|
79
|
+
assert.equal(fs.existsSync(path.join(target, "docs", "one.txt")), false);
|
|
80
|
+
assert.equal(fs.existsSync(path.join(target, ".kontourai")), false);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("provision core rejects destination paths whose existing ancestor escapes through a symlink", async () => {
|
|
84
|
+
const kit = fixture([entry("one", "one.txt", "linked/one.txt")]);
|
|
85
|
+
const target = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-link-target-"));
|
|
86
|
+
const outside = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-link-outside-"));
|
|
87
|
+
fs.symlinkSync(outside, path.join(target, "linked"), "dir");
|
|
88
|
+
await assert.rejects(() => provisionKit(kit, target), /escapes consumer repository/);
|
|
89
|
+
assert.equal(fs.existsSync(path.join(outside, "one.txt")), false);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("provision rejects a source that resolves outside the kit through a symlink", async () => {
|
|
93
|
+
const kit = fixture([entry("host", "host.txt", "copied.txt")]);
|
|
94
|
+
const outside = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-src-outside-"));
|
|
95
|
+
const secret = path.join(outside, "secret.txt");
|
|
96
|
+
fs.writeFileSync(secret, "off-kit-secret\n");
|
|
97
|
+
fs.symlinkSync(secret, path.join(kit, "payload", "host.txt"));
|
|
98
|
+
|
|
99
|
+
const errors = await validateKitRepository(kit);
|
|
100
|
+
assert.equal(errors.some((error) => error.includes("must not resolve outside the kit directory")), true, errors.join("\n"));
|
|
101
|
+
|
|
102
|
+
const target = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-src-target-"));
|
|
103
|
+
await assert.rejects(() => provisionKit(kit, target), /escapes the kit directory|validation failed/);
|
|
104
|
+
assert.equal(fs.existsSync(path.join(target, "copied.txt")), false);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("init activation provisions create-only and reports rerun conflicts without failing", () => {
|
|
108
|
+
const kit = fixture([entry("one", "one.txt", "docs/one.txt")]);
|
|
109
|
+
const target = fs.mkdtempSync(path.join(os.tmpdir(), "kit-provision-init-"));
|
|
110
|
+
const install = spawnSync(process.execPath, ["build/src/cli.js", "kit", "install", kit, "--dest", target], { encoding: "utf8" });
|
|
111
|
+
assert.equal(install.status, 0, `${install.stdout}\n${install.stderr}`);
|
|
112
|
+
const args = ["build/src/cli.js", "init", "--runtime", "codex", "--dest", target, "--telemetry-sink", "local-files", "--activate-kit", "fixture", "--yes"];
|
|
113
|
+
const first = spawnSync(process.execPath, args, { encoding: "utf8" });
|
|
114
|
+
assert.equal(first.status, 0, `${first.stdout}\n${first.stderr}`);
|
|
115
|
+
assert.equal(fs.readFileSync(path.join(target, "docs", "one.txt"), "utf8"), "one-new\n");
|
|
116
|
+
|
|
117
|
+
fs.writeFileSync(path.join(target, "docs", "one.txt"), "consumer-owned\n");
|
|
118
|
+
const second = spawnSync(process.execPath, args, { encoding: "utf8" });
|
|
119
|
+
assert.equal(second.status, 0, `${second.stdout}\n${second.stderr}`);
|
|
120
|
+
assert.match(`${second.stdout}\n${second.stderr}`, /skipped existing provision 'docs\/one.txt'/);
|
|
121
|
+
assert.equal(fs.readFileSync(path.join(target, "docs", "one.txt"), "utf8"), "consumer-owned\n");
|
|
122
|
+
});
|